about summary refs log tree commit diff
diff options
context:
space:
mode:
authorclubby789 <jamie@hill-daniel.co.uk>2025-03-09 23:42:48 +0000
committerclubby789 <jamie@hill-daniel.co.uk>2025-03-10 14:18:56 +0000
commit28bd22c3d9a477ff9b7b85782fb517c29b58ed88 (patch)
treec8dc0b6546879027c1e59e5a9a28753a0f56d4c0
parent3ea711f17e3946ac3f4df11691584e2c56b4b0cf (diff)
downloadrust-28bd22c3d9a477ff9b7b85782fb517c29b58ed88.tar.gz
rust-28bd22c3d9a477ff9b7b85782fb517c29b58ed88.zip
rustdoc: Gate unstable `doc(cfg())` predicates
-rw-r--r--src/librustdoc/clean/cfg.rs14
-rw-r--r--src/librustdoc/clean/types.rs7
-rw-r--r--src/librustdoc/doctest/rust.rs2
-rw-r--r--tests/rustdoc-ui/doc-cfg-unstable.rs10
-rw-r--r--tests/rustdoc-ui/doc-cfg-unstable.stderr23
5 files changed, 45 insertions, 11 deletions
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index ab169f3c2a4..1541e7201ce 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -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)),
         }
     }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 9e9cd528834..e70511a798a 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1056,6 +1056,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) => {
diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs
index 907e2a3eb2f..b12c516a827 100644
--- a/src/librustdoc/doctest/rust.rs
+++ b/src/librustdoc/doctest/rust.rs
@@ -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;
         }
diff --git a/tests/rustdoc-ui/doc-cfg-unstable.rs b/tests/rustdoc-ui/doc-cfg-unstable.rs
new file mode 100644
index 00000000000..14c2e83ec85
--- /dev/null
+++ b/tests/rustdoc-ui/doc-cfg-unstable.rs
@@ -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() {}
diff --git a/tests/rustdoc-ui/doc-cfg-unstable.stderr b/tests/rustdoc-ui/doc-cfg-unstable.stderr
new file mode 100644
index 00000000000..54de3b178ed
--- /dev/null
+++ b/tests/rustdoc-ui/doc-cfg-unstable.stderr
@@ -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`.