-
Notifications
You must be signed in to change notification settings - Fork 13.7k
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.
☔ The latest upstream changes (presumably #137229) made this pull request unmergeable. Please resolve the merge conflicts. |
a48b69b
to
491e1ef
Compare
Fixed merge conflict. |
This PR was rebased onto a different master 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. |
|
|
||
If no argument is specified (ie `#[doc(auto_cfg)]`), it's the same as writing `#[doc(auto_cfg = true)]`. | ||
|
||
### `#[doc(cfg(...))]` |
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.
It seems a bit odd to have doc(cfg(...))
listed in between two different forms of doc(auto_cfg)
```text | ||
Available on (Windows or Unix) and non-Unix only. | ||
``` |
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.
This case seems like something that could be improved in the future, but mostly unrelated to the feature being added here
// doesn't matter at this point. | ||
// | ||
// We need to pass this empty `CfgInfo` because `merge_attrs` is used when computing the `cfg`. | ||
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.
seems slightly inefficient but probably acceptable...
if !hidden.contains(self) { | ||
Some(self.clone()) | ||
} else { | ||
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.
This means that doc(auto_cfg(hide(feature)))
will not hide all features... is this the behavior we want?
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.
This is the one described in the RFC. We cannot hide just all feature = ""
cfg
s.
src/librustdoc/clean/types.rs
Outdated
/// This type keeps track of (doc) cfg information as we go down the item tree. | ||
#[derive(Clone, Debug)] | ||
pub(crate) struct CfgInfo { | ||
/// List of `doc(auto_cfg(hide(...)))` cfgs. |
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.
/// List of `doc(auto_cfg(hide(...)))` cfgs. | |
/// List of currently active `doc(auto_cfg(hide(...)))` cfgs, minus currently active `doc(auto_cfg(show(...)))` cfgs. |
is this correct?
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.
It is indeed!
src/librustdoc/clean/types.rs
Outdated
Some(Arc::new(cfg_info.current_cfg.clone())) | ||
} | ||
} else { | ||
// Since we always want to collect all `cfg` items, we remove the hidden ones afterward. |
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.
Saying "always" in a branch that is conditionally executed seems a bit confusing imo.
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.
True, rewording it.
if let Attribute::Unparsed(ref mut normal) = attr | ||
&& let [ident] = &*normal.path.segments | ||
{ |
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 thought we were treating target_feature
as doc(cfg(target_feature))
? Why do we keep it before and not now?
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.
No, the two are different. We handle attributes copy and doc(cfg())
inheritance in different locations as they rely on different rules. doc(cfg())
inherits from the parent item whereas attributes are copied only for reexports.
#[doc(auto_cfg(hide(true)))] //~ ERROR | ||
#[doc(auto_cfg(hide(42)))] //~ ERROR | ||
#[doc(auto_cfg(hide("a")))] //~ ERROR | ||
#[doc(auto_cfg(hide(foo::bar)))] //~ 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.
#[doc(auto_cfg(hide(true)))] //~ ERROR | |
#[doc(auto_cfg(hide(42)))] //~ ERROR | |
#[doc(auto_cfg(hide("a")))] //~ ERROR | |
#[doc(auto_cfg(hide(foo::bar)))] //~ ERROR | |
#[doc(auto_cfg(hide(true)))] //~ ERROR | |
#[doc(auto_cfg(hide(42)))] //~ ERROR | |
#[doc(auto_cfg(hide("a")))] //~ ERROR | |
#[doc(auto_cfg(hide(foo::bar)))] //~ ERROR | |
#[doc(auto_cfg = hide(true)] //~ ERROR | |
#[doc(auto_cfg = 42)] //~ ERROR | |
#[doc(auto_cfg = "a")] //~ ERROR | |
#[doc(auto_cfg = foo::bar)] //~ ERROR |
more testcases
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 can't put all of them otherwise it triggers earlier rustc errors:
error: expected unsuffixed literal, found `hide`
--> $DIR/doc-cfg.rs:16:18
|
LL | #[doc(auto_cfg = hide(true))]
| ^^^^
|
help: surround the identifier with quotation marks to make it into a string literal
|
LL | #[doc(auto_cfg = "hide"(true))]
| + +
error: expected unsuffixed literal, found `foo`
--> $DIR/doc-cfg.rs:19:18
|
LL | #[doc(auto_cfg = foo::bar)]
| ^^^
|
help: surround the identifier with quotation marks to make it into a string literal
|
LL | #[doc(auto_cfg = "foo"::bar)]
| + +
error: aborting due to 2 previous errors
@@ -0,0 +1,22 @@ | |||
// Checks that `cfg` are correctly applied on inlined reexports. |
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 this also check that cfg
s don't get applied on non-inlined reexports?
#![feature(doc_cfg)] | ||
|
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.
Does this mean target_feature
will no longer result in any note on stable rustdoc? Or will we still display the attribute itself?
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.
Nothing will be displayed. That's what happens when a PR changing a lot of things waits for too long. ^^'
That's good in any case 👍 This PR should just update the implementation according to the latest version of the merged RFC. I don't know if we have written that down in our new Forge docs (I hope so) but a feature stabilization would of course require another FCP, the one from the RFC isn't sufficient for that. Moreover, not stabilizing here / now / immediately allows us to gather more user feedback (esp. since the changes made by this PR are non-trivial). Heck, we could even issue a "call for testing" on the official blog – anything to make the eventual stabilization run as smoothly as possible. |
I was planning to keep it unstable for at least a few months and to enable it in some big crates to gather some usage and see if everything is working as expected. And in any case: any stabilization PR must go through FCP (we should check if we mention that in the forge ^^'). |
Oh also: applied suggestions from @lolbinarycat. :) |
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