about summary refs log tree commit diff
path: root/compiler/rustc_passes
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_passes')
-rw-r--r--compiler/rustc_passes/messages.ftl9
-rw-r--r--compiler/rustc_passes/src/check_attr.rs53
-rw-r--r--compiler/rustc_passes/src/errors.rs14
3 files changed, 60 insertions, 16 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 870e0a90b54..19014f37c66 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -143,6 +143,15 @@ passes_doc_attribute_not_attribute =
 passes_doc_cfg_hide_takes_list =
     `#[doc(cfg_hide(...))]` takes a list of attributes
 
+passes_doc_auto_cfg_expects_hide_or_show =
+    `only "hide" or "show" are allowed in "#[doc(auto_cfg(...))]"`
+
+passes_doc_auto_cfg_hide_show_expects_list =
+    `#![doc(auto_cfg({$attr_name}(...)))]` only expects a list of items
+
+passes_doc_auto_cfg_wrong_literal =
+    `expected boolean for #[doc(auto_cfg = ...)]`
+
 passes_doc_expect_str =
     doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 007353f136d..3dc232a35ec 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1160,16 +1160,43 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// Check that the `#![doc(cfg_hide(...))]` attribute only contains a list of attributes.
-    ///
-    fn check_doc_cfg_hide(&self, meta: &MetaItemInner, hir_id: HirId) {
-        if meta.meta_item_list().is_none() {
-            self.tcx.emit_node_span_lint(
-                INVALID_DOC_ATTRIBUTES,
-                hir_id,
-                meta.span(),
-                errors::DocCfgHideTakesList,
-            );
+    /// Check that the `#![doc(auto_cfg(..))]` attribute has expected input.
+    fn check_doc_auto_cfg(&self, meta: &MetaItemInner, hir_id: HirId) {
+        let MetaItemInner::MetaItem(meta) = meta else {
+            unreachable!();
+        };
+        match &meta.kind {
+            MetaItemKind::Word => {}
+            MetaItemKind::NameValue(lit) => {
+                if !matches!(lit.kind, LitKind::Bool(_)) {
+                    self.tcx.emit_node_span_lint(
+                        INVALID_DOC_ATTRIBUTES,
+                        hir_id,
+                        meta.span,
+                        errors::DocAutoCfgWrongLiteral,
+                    );
+                }
+            }
+            MetaItemKind::List(list) => {
+                for item in list {
+                    let Some(attr_name) = item.name() else { continue };
+                    if attr_name != sym::hide && attr_name != sym::show {
+                        self.tcx.emit_node_span_lint(
+                            INVALID_DOC_ATTRIBUTES,
+                            hir_id,
+                            meta.span,
+                            errors::DocAutoCfgExpectsHideOrShow,
+                        );
+                    } else if item.meta_item_list().is_none() {
+                        self.tcx.emit_node_span_lint(
+                            INVALID_DOC_ATTRIBUTES,
+                            hir_id,
+                            meta.span,
+                            errors::DocAutoCfgHideShowExpectsList { attr_name: attr_name.as_str() },
+                        );
+                    }
+                }
+            }
         }
     }
 
@@ -1245,10 +1272,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             self.check_attr_crate_level(attr, style, meta, hir_id);
                         }
 
-                        Some(sym::cfg_hide) => {
-                            if self.check_attr_crate_level(attr, style, meta, hir_id) {
-                                self.check_doc_cfg_hide(meta, hir_id);
-                            }
+                        Some(sym::auto_cfg) => {
+                            self.check_doc_auto_cfg(meta, hir_id);
                         }
 
                         Some(sym::inline | sym::no_inline) => {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index cfd6b9e6dff..6cc0bd6ce48 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -309,8 +309,18 @@ pub(crate) struct DocTestLiteral;
 pub(crate) struct DocTestTakesList;
 
 #[derive(LintDiagnostic)]
-#[diag(passes_doc_cfg_hide_takes_list)]
-pub(crate) struct DocCfgHideTakesList;
+#[diag(passes_doc_auto_cfg_wrong_literal)]
+pub(crate) struct DocAutoCfgWrongLiteral;
+
+#[derive(LintDiagnostic)]
+#[diag(passes_doc_auto_cfg_expects_hide_or_show)]
+pub(crate) struct DocAutoCfgExpectsHideOrShow;
+
+#[derive(LintDiagnostic)]
+#[diag(passes_doc_auto_cfg_hide_show_expects_list)]
+pub(crate) struct DocAutoCfgHideShowExpectsList<'a> {
+    pub attr_name: &'a str,
+}
 
 #[derive(LintDiagnostic)]
 #[diag(passes_doc_test_unknown_any)]