-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Fix doc_cfg not working as expected on trait impls
#153964
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
Merged
rust-bors
merged 5 commits into
rust-lang:main
from
GuillaumeGomez:fix-trait-impl-doc-cfg
Mar 24, 2026
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
953210c
Fix `doc_cfg` not working as expected on trait impls
GuillaumeGomez 73fe4c5
Add regression test for #153655
GuillaumeGomez 6fcd011
Correctly handle rustdoc `PlaceholderImplItem` in lints
GuillaumeGomez 24e40f0
Add more comments to explain code
GuillaumeGomez 19876d1
Simplify code and improve code comments
GuillaumeGomez File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -372,6 +372,19 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { | |
| && !inherits_doc_hidden(tcx, item_def_id, None) | ||
| } | ||
|
|
||
| #[inline] | ||
| fn add_impl_to_current_mod(&mut self, item: &'tcx hir::Item<'_>, impl_: hir::Impl<'_>) { | ||
| self.add_to_current_mod( | ||
| item, | ||
| // The symbol here is used as a "sentinel" value and has no meaning in | ||
| // itself. It just tells that this is an inlined impl and that it should not | ||
| // be cleaned as a normal `ImplItem` but instead as a `PlaceholderImplItem`. | ||
| // It's to ensure that `doc_cfg` inheritance works as expected. | ||
| if impl_.of_trait.is_none() { None } else { Some(rustc_span::symbol::kw::Impl) }, | ||
| None, | ||
| ); | ||
| } | ||
|
|
||
| #[inline] | ||
| fn add_to_current_mod( | ||
| &mut self, | ||
|
|
@@ -426,12 +439,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { | |
| // } | ||
| // Bar::bar(); | ||
| // ``` | ||
| if let hir::ItemKind::Impl(impl_) = item.kind && | ||
| // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick | ||
| // them up regardless of where they're located. | ||
| impl_.of_trait.is_none() | ||
| { | ||
| self.add_to_current_mod(item, None, None); | ||
| if let hir::ItemKind::Impl(impl_) = item.kind { | ||
| self.add_impl_to_current_mod(item, impl_); | ||
| } | ||
| return; | ||
| } | ||
|
|
@@ -530,10 +539,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { | |
| } | ||
| } | ||
| hir::ItemKind::Impl(impl_) => { | ||
| // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick | ||
| // Don't duplicate impls when inlining, we'll pick | ||
| // 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 { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea. |
||
| self.add_impl_to_current_mod(item, impl_); | ||
| } | ||
| } | ||
| } | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| // This test ensures that `doc_cfg` feature is working as expected on trait impls. | ||
| // Regression test for <https://github.com/rust-lang/rust/issues/153655>. | ||
|
|
||
| #![feature(doc_cfg)] | ||
| #![doc(auto_cfg(hide( | ||
| target_pointer_width = "64", | ||
| )))] | ||
|
|
||
| #![crate_name = "foo"] | ||
|
|
||
| pub trait Trait { | ||
| fn f(&self) {} | ||
| } | ||
|
|
||
| pub trait Bob { | ||
| fn bob(&self) {} | ||
| } | ||
|
|
||
| pub trait Foo { | ||
| fn foo(&self) {} | ||
| } | ||
|
|
||
| pub struct X; | ||
|
|
||
| //@has 'foo/struct.X.html' | ||
| //@count - '//*[@id="impl-Bob-for-X"]' 1 | ||
| //@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0 | ||
| //@count - '//*[@id="impl-Trait-for-X"]' 1 | ||
| //@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0 | ||
|
|
||
| // If you need to update this XPath, in particular `item-info`, update all | ||
| // the others in this file. | ||
| //@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1 | ||
|
|
||
| //@has 'foo/trait.Trait.html' | ||
| //@count - '//*[@id="impl-Trait-for-X"]' 1 | ||
| //@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0 | ||
| #[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] | ||
| #[doc(auto_cfg(hide(target_arch = "wasm32")))] | ||
| mod imp { | ||
| impl super::Trait for super::X { fn f(&self) {} } | ||
| } | ||
|
|
||
| //@has 'foo/trait.Bob.html' | ||
| //@count - '//*[@id="impl-Bob-for-X"]' 1 | ||
| //@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0 | ||
| #[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] | ||
| #[doc(auto_cfg = false)] | ||
| mod imp2 { | ||
| impl super::Bob for super::X { fn bob(&self) {} } | ||
| } | ||
|
|
||
| //@has 'foo/trait.Foo.html' | ||
| //@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1 | ||
| // We use this to force xpath tests to be updated if `item-info` class is changed. | ||
| #[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] | ||
| mod imp3 { | ||
| impl super::Foo for super::X { fn foo(&self) {} } | ||
| } | ||
|
|
||
| pub struct Y; | ||
|
|
||
| //@has 'foo/struct.Y.html' | ||
| //@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 | ||
| //@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0 | ||
| #[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] | ||
| #[doc(auto_cfg(hide(target_arch = "wasm32")))] | ||
| mod imp4 { | ||
| impl super::Y { pub fn plain_auto() {} } | ||
| } | ||
|
|
||
| pub struct Z; | ||
|
|
||
| //@has 'foo/struct.Z.html' | ||
| //@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 | ||
| //@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0 | ||
| #[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] | ||
| #[doc(auto_cfg = false)] | ||
| mod imp5 { | ||
| impl super::Z { pub fn plain_auto() {} } | ||
| } | ||
|
|
||
| // The "witness" which has the item info. | ||
| pub struct W; | ||
|
|
||
| //@has 'foo/struct.W.html' | ||
| //@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1 | ||
| //@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 1 | ||
| #[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))] | ||
| mod imp6 { | ||
| impl super::W { pub fn plain_auto() {} } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.