Rollup merge of #138293 - clubby789:doc-cfg-gate, r=GuillaumeGomez

rustdoc: Gate unstable `doc(cfg())` predicates

Fixes #138113

Since the extraction process treats `cfg(true)` as having no cfg attribute, we have to do the gating during parsing; so we remove the unused `features` arg from `Cfg::matches`
This commit is contained in:
Michael Goulet 2025-03-23 14:59:30 -04:00 committed by GitHub
commit 856ba39bd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 61 additions and 11 deletions

View File

@ -8,7 +8,6 @@ use std::{mem, ops};
use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit};
use rustc_data_structures::fx::FxHashSet;
use rustc_feature::Features;
use rustc_session::parse::ParseSess;
use rustc_span::Span;
use rustc_span::symbol::{Symbol, sym};
@ -132,18 +131,13 @@ impl Cfg {
/// Checks whether the given configuration can be matched in the current session.
///
/// Equivalent to `attr::cfg_matches`.
// FIXME: Actually make use of `features`.
pub(crate) fn matches(&self, psess: &ParseSess, features: Option<&Features>) -> bool {
pub(crate) fn matches(&self, psess: &ParseSess) -> bool {
match *self {
Cfg::False => false,
Cfg::True => true,
Cfg::Not(ref child) => !child.matches(psess, features),
Cfg::All(ref sub_cfgs) => {
sub_cfgs.iter().all(|sub_cfg| sub_cfg.matches(psess, features))
}
Cfg::Any(ref sub_cfgs) => {
sub_cfgs.iter().any(|sub_cfg| sub_cfg.matches(psess, features))
}
Cfg::Not(ref child) => !child.matches(psess),
Cfg::All(ref sub_cfgs) => sub_cfgs.iter().all(|sub_cfg| sub_cfg.matches(psess)),
Cfg::Any(ref sub_cfgs) => sub_cfgs.iter().any(|sub_cfg| sub_cfg.matches(psess)),
Cfg::Cfg(name, value) => psess.config.contains(&(name, value)),
}
}

View File

@ -1068,6 +1068,13 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
.meta_item()
.and_then(|item| rustc_expand::config::parse_cfg(item, sess))
{
// The result is unused here but we can gate unstable predicates
rustc_attr_parsing::cfg_matches(
cfg_mi,
tcx.sess,
rustc_ast::CRATE_NODE_ID,
Some(tcx.features()),
);
match Cfg::parse(cfg_mi) {
Ok(new_cfg) => cfg &= new_cfg,
Err(e) => {

View File

@ -98,7 +98,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())
&& !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features()))
&& !cfg.matches(&self.tcx.sess.psess)
{
return;
}

View File

@ -0,0 +1,16 @@
// Ensure that `doc(cfg())` respects `check-cfg`
// Currently not properly working
#![feature(doc_cfg)]
#![deny(unexpected_cfgs)]
//@revisions: no_check cfg_empty cfg_foo
//@[cfg_empty] compile-flags: --check-cfg cfg()
//@[cfg_foo] compile-flags: --check-cfg cfg(foo)
//@[no_check] check-pass
//@[cfg_empty] check-pass
//@[cfg_empty] known-bug: #138358
//@[cfg_foo] check-pass
#[doc(cfg(foo))]
pub fn foo() {}

View File

@ -0,0 +1,10 @@
// #138113: rustdoc didn't gate unstable predicates inside `doc(cfg(..))`
#![feature(doc_cfg)]
// `cfg_boolean_literals`
#[doc(cfg(false))] //~ ERROR `cfg(false)` is experimental and subject to change
pub fn cfg_boolean_literals() {}
// `cfg_version`
#[doc(cfg(sanitize = "thread"))] //~ ERROR `cfg(sanitize)` is experimental and subject to change
pub fn cfg_sanitize() {}

View File

@ -0,0 +1,23 @@
error[E0658]: `cfg(false)` is experimental and subject to change
--> $DIR/doc-cfg-unstable.rs:5:11
|
LL | #[doc(cfg(false))]
| ^^^^^
|
= note: see issue #131204 <https://github.com/rust-lang/rust/issues/131204> for more information
= help: add `#![feature(cfg_boolean_literals)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `cfg(sanitize)` is experimental and subject to change
--> $DIR/doc-cfg-unstable.rs:9:11
|
LL | #[doc(cfg(sanitize = "thread"))]
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #39699 <https://github.com/rust-lang/rust/issues/39699> for more information
= help: add `#![feature(cfg_sanitize)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.