Fix doc_cfg not working as expected on trait impls#153964
Fix doc_cfg not working as expected on trait impls#153964GuillaumeGomez wants to merge 4 commits intorust-lang:mainfrom
doc_cfg not working as expected on trait impls#153964Conversation
This comment has been minimized.
This comment has been minimized.
doc_cfg not working as expected on trait impls
This comment has been minimized.
This comment has been minimized.
|
Not great that |
|
And CI passed. \o/ |
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 |
There was a problem hiding this comment.
nit: ambiguous pronoun, this would be less ambiguous if "this" was replaced with an actual name.
src/librustdoc/passes/stripper.rs
Outdated
|
|
||
| clean::ImplItem(..) => {} | ||
|
|
||
| // They have no use anymore, so always remove them. |
There was a problem hiding this comment.
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. | |||
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Doesn't hurt to add one in the same test I guess. Gonna add a test for non-auto doc(cfg(...)) too.
| match item.kind { | ||
| ItemKind::Impl(ref impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), | ||
| ItemKind::Impl(ref impl_) => { | ||
| return clean_impl(impl_, item.owner_id.def_id, cx, renamed); |
There was a problem hiding this comment.
what does it mean for an impl to be renamed?
There was a problem hiding this comment.
The explanation is on the clean_impl function but I can copy/paste it here too.
ce71ac8 to
2dd7677
Compare
This comment has been minimized.
This comment has been minimized.
|
Added comments and greatly extended the tests. |
This comment has been minimized.
This comment has been minimized.
|
Seems like a flaky failure. Restarted CI. |
There was a problem hiding this comment.
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.
| | clean::ProvidedAssocConstItem(..) | ||
| | clean::ImplAssocConstItem(..) | ||
| | clean::RequiredAssocTypeItem(..) | ||
| | clean::PlaceholderImplItem |
There was a problem hiding this comment.
This made me realize that we don't actually have a test for how rustdoc::missing_doc_code_examples interacts with inherent impls (we do have them for trait impls, which is what is relevant to this PR, and what I was initially checking).
There was a problem hiding this comment.
Gonna send another PR for it then. :)
| clean::PlaceholderImplItem => { | ||
| // The "real" impl items are handled below. | ||
| return; | ||
| } |
There was a problem hiding this comment.
note: we do have test coverage for doc coverage involving both types of impl. good.
| if let ItemKind::ImplItem(_) = item.kind | ||
| && let Some(cfg_info) = self.impl_cfg_info.remove(&item.item_id) | ||
| { | ||
| self.cfg_info = cfg_info; | ||
| } | ||
|
|
||
| if let ItemKind::PlaceholderImplItem = item.kind { |
There was a problem hiding this comment.
nit: if let with no new bindings introduced. might be more intuitive if these were written with matches!? but this pattern is used a bit around rustdoc, so if you'd rather keep it how it is that's fine.
There was a problem hiding this comment.
I tend to prefer inline code over macros if I can, and I have to admit I find this let binding funny. Brain fart of the day I guess. ^^'
| self.add_to_current_mod( | ||
| item, | ||
| if impl_.of_trait.is_none() { | ||
| None | ||
| } else { | ||
| Some(rustc_span::symbol::kw::Impl) | ||
| }, | ||
| None, | ||
| ); |
There was a problem hiding this comment.
This seems like a little bit of a magic value, I'd at least like if this special value was documented somewhere, perhaps on the doc comment of Module::items. I understand the use of a sentinel here because the alternative involves adding a new field to the tuple in the items Vec, or refactoring that into a more principled enum, which I'm sure would be quite the undertaking.
Actually, this isn't quite a sentinel value, is it, because Impl items in this context don't actually care about the inner value of renamed, just if it is None, correct?
There was a problem hiding this comment.
Yeah. I'll add a comment to make that clear though because it really comes out of nowhere.
2dd7677 to
3f0f7d7
Compare
|
I added code comments to explain that the symbol is used as a sentinel value. |
| if impl_.of_trait.is_none() { | ||
| None | ||
| } else { | ||
| Some(rustc_span::symbol::kw::Impl) | ||
| }, |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Context: this argument is what an inlined item is renamed into. So no, I don't want to rename it. 😝
…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
…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
…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
This comment has been minimized.
This comment has been minimized.
3f0f7d7 to
2752dc5
Compare
|
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. |
|
|
Fixed merge conflict. |
Fixes #153655.
I spent waaaaay too much time on this fix. So the current issue is that rustdoc gets its items in two passes:
Because of that, the trait impls are not stored "correctly" in the rustdoc AST, meaning that the
propagate_doc_cfgpass 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 thecfg"context" (more clear when reading the code 😛) and re-use it later on when the "real" impl comes up.r? @lolbinarycat