-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Implement RFC 3631: add rustdoc doc_cfg features #138907
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
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
Noted! And that will be a nice improvement, thanks! Just one thing left for the cfg expansion missing: |
Do you mean like in #138515? :) |
You're my hero! Gonna need to handle this new attribute then. :) |
4a05a52
to
3d2eef1
Compare
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #138923) made this pull request unmergeable. Please resolve the merge conflicts. |
d88598f
to
db25eea
Compare
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #138927) made this pull request unmergeable. Please resolve the merge conflicts. |
b8cb424
to
b581ce1
Compare
This comment has been minimized.
This comment has been minimized.
b581ce1
to
1cb7fac
Compare
This comment has been minimized.
This comment has been minimized.
71369a1
to
fbee8a9
Compare
This comment has been minimized.
This comment has been minimized.
Rebased and replaced usage of removed |
☔ The latest upstream changes (presumably #140695) made this pull request unmergeable. Please resolve the merge conflicts. |
Fixed merge conflict. |
I'll try and take a look at this impl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code generally looks good! Needs some docs and then we should be good to go, I think. Would ideally like a second review but overall I think it's fine.
@@ -776,3 +694,271 @@ will be split as follows: | |||
"you today?", | |||
] | |||
``` | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These docs could probably use an editorial pass but I'd prefer to skip that for now, it's a separate step of the stabilization process. So I'm not reviewing these too closely, they seem to be roughly accurate.
Added missing docs, renamed some functions too to be easier to understand what they do just by their name (doc is good but good naming is important too 😅). I applied the code improvement suggestion and improved the error message. Thanks a lot! |
A job failed! Check out the build log: (web) (plain) Click to see the possible cause of the failure (guessed by this bot)
|
`#![doc(auto_cfg({$attr_name}(...)))]` expects a list of items | ||
|
||
passes_doc_auto_cfg_hide_show_unexpected_item = | ||
`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/values items |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/values items | |
`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or key/value items |
} | ||
MetaItemKind::List(list) => { | ||
for item in list { | ||
let Some(attr_name) = item.name() else { continue }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the else
case emit an error since we've received an invalid entry for the auto_cfg list? E.g. doc(auto_cfg(42))
or doc(auto_cfg(foo::bar))
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add test cases for this missing error, along with the ones below.
); | ||
} else if let Some(list) = item.meta_item_list() { | ||
for item in list { | ||
if item.meta_item_list().is_some() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we also error if there is no meta item list but the item is an invalid cfg (e.g. a boolean, or a multi-segment path)?
hir_id, | ||
item.span(), | ||
errors::DocAutoCfgHideShowUnexpectedItem { | ||
attr_name: attr_name.as_str(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attr_name
is either "hide" or "show" here, not the invalid cfg entry.
INVALID_DOC_ATTRIBUTES, | ||
hir_id, | ||
meta.span, | ||
errors::DocAutoCfgHideShowExpectsList { attr_name: attr_name.as_str() }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
fn default() -> Self { | ||
Self { | ||
hidden_cfg: [ | ||
Cfg::Cfg(sym::test, None), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this answers my question above about why you removed test
from the list of hidden cfgs 🙃
Any particular reason why you added it here though? The RFC specified only doc
and doctest
as hidden by default, not that we necessarily have to strictly follow that.
/// This function checks if a same `cfg` is present in both `auto_cfg(hide(...))` and | ||
/// `auto_cfg(show(...))` on the same item. If so, it emits an error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This function does more than just error handling since it also updates the cfg_info.hidden_cfg
set. But the docs imply otherwise. Also, maybe use an enum instead of is_show: bool
?
if let Some(first_change) = changed_auto_active_status { | ||
if cfg_info.auto_cfg_active != value { | ||
tcx.sess.dcx().struct_span_err( | ||
vec![first_change, attr.span], | ||
"`auto_cfg` was disabled and enabled more than once on the same item", | ||
).emit(); | ||
return None; | ||
} | ||
} else { | ||
changed_auto_active_status = Some(attr.span); | ||
} | ||
cfg_info.auto_cfg_active = value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you extract this as a closure and then use it in all 3 match arms? Or find some other way to avoid having 3 copies of this code.
if !cfg_info.parent_is_doc_cfg { | ||
cfg_info.current_cfg = Cfg::True; | ||
cfg_info.parent_is_doc_cfg = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little bit confused about why we have cfg_info.parent_is_doc_cfg
rather than a has_doc_cfg
local variable. Maybe I'm missing something though. Can you help me understand what's going on with this flag better?
@@ -117,7 +116,7 @@ impl HirCollector<'_> { | |||
) { | |||
let ast_attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); | |||
if let Some(ref cfg) = | |||
extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default()) | |||
extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &mut CfgInfo::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drive-by comment: Obviously this code existed before, but wondering if it'd make more sense to use the rustc cfg_matches
logic instead here. Since we only care about the semantic meaning of the cfg
not its display in rustdoc.
@@ -593,7 +594,7 @@ pub(crate) fn build_impl( | |||
}); | |||
} | |||
|
|||
let (merged_attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs); | |||
let (merged_attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs, &mut CfgInfo::default()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little confused about the correctness of this. Seems like inlined impls should be subject to the auto_cfg specified for the place they're inlined into, but this puts them in a fresh context...?
@@ -1,5 +1,6 @@ | |||
#![doc(cfg_hide(test))] | |||
//~^ ERROR `#[doc(cfg_hide)]` is experimental | |||
// FIXME: Remove this file once feature is removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hasn't it been removed now?
Also, can you add some tests to make sure doc(auto_cfg)
(perhaps with some different combinations of arguments, including none, to auto_cfg
) and doc(cfg)
are still feature-gated?
☔ The latest upstream changes (presumably #141668) made this pull request unmergeable. Please resolve the merge conflicts. |
Implementation of rust-lang/rfcs#3631.
This implementation actually resulted in a lot of simplifications:
cfg
computation is now done in one place:propagate_doc_cfg.rs
. Because (trait)impl
s are not retrieved at the same time as the other items, we cannot perform this computation in the clean process, it needs to be after.cfg
inheritance, we can keep track of them in one place (inpropagate_doc_cfg.rs
), meaning we don't need to copy an item's attributes to its children anymore. Only exception: impl items. For them we clone onlycfg
attributes.propagate_doc_cfg.rs
is also now much simpler, much less need to keep track of parents, since everything we need is handled by the newCfgInfo
type.Cfg::simplify_with
could either be removed or at least used directly intopropagate_doc_cfg.rs
when we computecfg
s. Considering how big the PR already is, I'll do it in a follow-up.I didn't remove the
doc_cfg*
features in this PR because some dependencies used inrustc
(likestdarch
) are using it, so we need to have a nightly released with this PR before I can switch to the new feature.r? ghost