Repository: rust-lang/rust
Pull request: rustdoc_missing_doc_code_examples: lint on macro_rules macros

<!-- homu-ignore:start -->
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.

This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using

    r? <reviewer name>
-->
<!-- homu-ignore:end -->

part of rust-lang/rust#154640 

accidentally built this on top of rust-lang/rust#154644, but since that PR is already approved it should be fine if we just wait for it to be merged.

r? @GuillaumeGomez 

Changed files:
filename: src/librustdoc/clean/types.rs
patch: @@ -453,6 +453,13 @@ impl Item {
         self.stability.is_some_and(|x| x.is_unstable())
     }
 
+    pub(crate) fn is_exported_macro(&self) -> bool {
+        match self.kind {
+            ItemKind::MacroItem(..) => find_attr!(&self.attrs.other_attrs, MacroExport { .. }),
+            _ => false,
+        }
+    }
+
     pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
         self.item_id
             .as_def_id()

filename: src/librustdoc/passes/check_doc_test_visibility.rs
patch: @@ -56,7 +56,8 @@ impl crate::doctest::DocTestVisitor for Tests {
 }
 
 pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
-    if !cx.cache.effective_visibilities.is_directly_public(cx.tcx, item.item_id.expect_def_id())
+    if !(cx.cache.effective_visibilities.is_directly_public(cx.tcx, item.item_id.expect_def_id())
+        || item.is_exported_macro())
         || matches!(
             item.kind,
             clean::StructFieldItem(_)

filename: src/librustdoc/passes/strip_hidden.rs
patch: @@ -3,7 +3,6 @@
 use std::mem;
 
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
-use rustc_hir::find_attr;
 use rustc_middle::ty::TyCtxt;
 use tracing::debug;
 
@@ -113,9 +112,7 @@ impl DocFolder for Stripper<'_, '_> {
             clean::ImplItem(..) => true,
             // If the macro has the `#[macro_export]` attribute, it means it's accessible at the
             // crate level so it should be handled differently.
-            clean::MacroItem(..) => {
-                find_attr!(&i.attrs.other_attrs, MacroExport { .. })
-            }
+            clean::MacroItem(..) => i.is_exported_macro(),
             _ => false,
         };
         let mut is_hidden = has_doc_hidden;

filename: tests/rustdoc-ui/lints/check.rs
patch: @@ -4,6 +4,7 @@
 
 #![feature(rustdoc_missing_doc_code_examples)] //~ WARN no documentation found for this crate's top-level module
 //~^ WARN
+#![feature(decl_macro)]
 
 #![warn(missing_docs)]
 #![warn(rustdoc::missing_doc_code_examples)]
@@ -12,3 +13,14 @@
 pub fn foo() {}
 //~^ WARN
 //~^^ WARN
+
+#[macro_export]
+macro_rules! bar {
+//~^ WARN missing documentation
+//~^^ WARN missing code example
+    () => {};
+}
+
+pub macro bar_v2() {}
+//~^ WARN missing documentation
+//~^^ WARN missing code example

filename: tests/rustdoc-ui/lints/check.stderr
patch: @@ -3,55 +3,81 @@ warning: missing documentation for the crate
    |
 LL | / #![feature(rustdoc_missing_doc_code_examples)]
 LL | |
-LL | |
-LL | | #![warn(missing_docs)]
+LL | | #![feature(decl_macro)]
 ...  |
-LL | | pub fn foo() {}
-   | |_______________^
+LL | | pub macro bar_v2() {}
+   | |_____________________^
    |
 note: the lint level is defined here
-  --> $DIR/check.rs:8:9
+  --> $DIR/check.rs:9:9
    |
 LL | #![warn(missing_docs)]
    |         ^^^^^^^^^^^^
 
 warning: missing documentation for a function
-  --> $DIR/check.rs:12:1
+  --> $DIR/check.rs:13:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^
 
+warning: missing documentation for a macro
+  --> $DIR/check.rs:18:1
+   |
+LL | macro_rules! bar {
+   | ^^^^^^^^^^^^^^^^
+
+warning: missing documentation for a macro
+  --> $DIR/check.rs:24:1
+   |
+LL | pub macro bar_v2() {}
+   | ^^^^^^^^^^^^^^^^
+
 warning: no documentation found for this crate's top-level module
   --> $DIR/check.rs:5:1
    |
 LL | / #![feature(rustdoc_missing_doc_code_examples)]
 LL | |
-LL | |
-LL | | #![warn(missing_docs)]
+LL | | #![feature(decl_macro)]
 ...  |
-LL | | pub fn foo() {}
-   | |_______________^
+LL | | pub macro bar_v2() {}
+   | |_____________________^
    |
    = help: The following guide may be of use:
            https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
 note: the lint level is defined here
-  --> $DIR/check.rs:10:9
+  --> $DIR/check.rs:11:9
    |
 LL | #![warn(rustdoc::all)]
    |         ^^^^^^^^^^^^
    = note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc::all)]`
 
 warning: missing code example in this documentation
-  --> $DIR/check.rs:12:1
+  --> $DIR/check.rs:13:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/check.rs:9:9
+  --> $DIR/check.rs:10:9
    |
 LL | #![warn(rustdoc::missing_doc_code_examples)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: 4 warnings emitted
+warning: missing code example in this documentation
+  --> $DIR/check.rs:24:1
+   |
+LL | pub macro bar_v2() {}
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: missing code example in this documentation
+  --> $DIR/check.rs:18:1
+   |
+LL | / macro_rules! bar {
+LL | |
+LL | |
+LL | |     () => {};
+LL | | }
+   | |_^
+
+warning: 8 warnings emitted