From 36a3c6d0e9136a6d5a0951b8deeacb29b7cf15f4 Mon Sep 17 00:00:00 2001 From: Malena Ohl Date: Sat, 7 Dec 2024 19:28:59 -0500 Subject: [PATCH] Add lint macro_now_doc_hidden --- src/lints/declarative_macro_missing.ron | 3 +- src/lints/macro_now_doc_hidden.ron | 40 +++++++++++++++++++ src/query.rs | 1 + .../macro_now_doc_hidden/new/Cargo.toml | 7 ++++ .../macro_now_doc_hidden/new/src/lib.rs | 40 +++++++++++++++++++ .../macro_now_doc_hidden/old/Cargo.toml | 7 ++++ .../macro_now_doc_hidden/old/src/lib.rs | 40 +++++++++++++++++++ .../declarative_macro_missing.snap | 6 +-- .../query_execution/macro_now_doc_hidden.snap | 21 ++++++++++ 9 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 src/lints/macro_now_doc_hidden.ron create mode 100644 test_crates/macro_now_doc_hidden/new/Cargo.toml create mode 100644 test_crates/macro_now_doc_hidden/new/src/lib.rs create mode 100644 test_crates/macro_now_doc_hidden/old/Cargo.toml create mode 100644 test_crates/macro_now_doc_hidden/old/src/lib.rs create mode 100644 test_outputs/query_execution/macro_now_doc_hidden.snap diff --git a/src/lints/declarative_macro_missing.ron b/src/lints/declarative_macro_missing.ron index ccb02cb8..9f295600 100644 --- a/src/lints/declarative_macro_missing.ron +++ b/src/lints/declarative_macro_missing.ron @@ -25,7 +25,6 @@ SemverQuery( current @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { item { ... on Macro { - visibility_limit @filter(op: "=", value: ["$public"]) name @filter(op: "=", value: ["%name"]) } } @@ -37,7 +36,7 @@ SemverQuery( "zero": 0, "true": true, }, - error_message: "A publicly-visible `macro_rules` declarative macro cannot be imported by its prior name. A `#[macro_export]` may have been removed, or the macro itself may have been renamed or removed entirely.", + error_message: "A `macro_rules` declarative macro cannot be imported by its prior name. The macro may have been renamed or removed entirely.", per_result_error_template: Some("macro_rules! {{name}}, previously in file {{span_filename}}:{{span_begin_line}}"), witness: ( hint_template: r#"{{name}}!(...);"# diff --git a/src/lints/macro_now_doc_hidden.ron b/src/lints/macro_now_doc_hidden.ron new file mode 100644 index 00000000..32170c0e --- /dev/null +++ b/src/lints/macro_now_doc_hidden.ron @@ -0,0 +1,40 @@ +SemverQuery( + id: "macro_now_doc_hidden", + human_readable_name: "macro is now #[doc(hidden)]", + description: "A declarative macro that was previously part of the public API is now #[doc(hidden)], requiring downstream users to acknowledge their reliance on non-public APIs.", + required_update: Major, + lint_level: Deny, + reference_link: Some("https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html#hidden"), + query: r#" + { + CrateDiff { + baseline { + item { + ... on Macro { + name @output @tag + public_api_eligible @filter(op: "=", value: ["$true"]) + } + } + } + current { + item { + ... on Macro { + name @filter(op: "=", value: ["%name"]) + doc_hidden @filter(op: "=", value: ["$true"]) + public_api_eligible @filter(op: "!=", value: ["$true"]) + span_: span @optional { + filename @output + begin_line @output + } + } + } + } + } + }"#, + arguments: { + "true": true, + }, + error_message: "A macro that was previously part of the public API is now #[doc(hidden)].", + per_result_error_template: Some("macro {{name}} in {{span_filename}}:{{span_begin_line}}"), + witness: None, +) diff --git a/src/query.rs b/src/query.rs index 37d2c163..69efa0cf 100644 --- a/src/query.rs +++ b/src/query.rs @@ -1095,6 +1095,7 @@ add_lints!( inherent_method_must_use_added, inherent_method_now_doc_hidden, inherent_method_unsafe_added, + macro_now_doc_hidden, method_parameter_count_changed, module_missing, non_exhaustive_struct_changed_type, diff --git a/test_crates/macro_now_doc_hidden/new/Cargo.toml b/test_crates/macro_now_doc_hidden/new/Cargo.toml new file mode 100644 index 00000000..008b90a8 --- /dev/null +++ b/test_crates/macro_now_doc_hidden/new/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "macro_now_doc_hidden" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/macro_now_doc_hidden/new/src/lib.rs b/test_crates/macro_now_doc_hidden/new/src/lib.rs new file mode 100644 index 00000000..2c6e5010 --- /dev/null +++ b/test_crates/macro_now_doc_hidden/new/src/lib.rs @@ -0,0 +1,40 @@ +/// Now hidden from docs +#[doc(hidden)] +#[macro_export] +macro_rules! will_be_hidden { + ($val:expr, $opts:expr) => { + println!("Processing {} with {:?}", $val, $opts); + }; +} + +/// A macro that stays public +#[macro_export] +macro_rules! stays_public { + () => { + println!("This macro remains public"); + }; +} + +// Already hidden macro that changes implementation but stays hidden +#[doc(hidden)] +#[macro_export] +macro_rules! already_hidden { + () => { + println!("Version 2"); + }; +} + +// Non-exported macro that becomes hidden - should not trigger +#[doc(hidden)] +macro_rules! non_exported_becomes_hidden { + () => { + println!("Not exported and now hidden"); + }; +} + +// Macro that was exported but is no longer exported - should not trigger +macro_rules! becomes_non_exported { + () => { + println!("No longer exported"); + }; +} diff --git a/test_crates/macro_now_doc_hidden/old/Cargo.toml b/test_crates/macro_now_doc_hidden/old/Cargo.toml new file mode 100644 index 00000000..008b90a8 --- /dev/null +++ b/test_crates/macro_now_doc_hidden/old/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "macro_now_doc_hidden" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/macro_now_doc_hidden/old/src/lib.rs b/test_crates/macro_now_doc_hidden/old/src/lib.rs new file mode 100644 index 00000000..796eb8d1 --- /dev/null +++ b/test_crates/macro_now_doc_hidden/old/src/lib.rs @@ -0,0 +1,40 @@ +/// A macro that will become hidden +#[macro_export] +macro_rules! will_be_hidden { + ($val:expr, $opts:expr) => { + println!("Processing {} with {:?}", $val, $opts); + }; +} + +/// A macro that stays public +#[macro_export] +macro_rules! stays_public { + () => { + println!("This macro remains public"); + }; +} + +// Already hidden macro that changes implementation but stays hidden +#[doc(hidden)] +#[macro_export] +macro_rules! already_hidden { + () => { + println!("Version 1"); + }; +} + +// Non-exported macro that becomes hidden - should not trigger +/// Some documentation +macro_rules! non_exported_becomes_hidden { + () => { + println!("Not exported"); + }; +} + +// Exported macro that becomes non-exported but not doc(hidden) - should not trigger +#[macro_export] +macro_rules! becomes_non_exported { + () => { + println!("Will become non-exported"); + }; +} diff --git a/test_outputs/query_execution/declarative_macro_missing.snap b/test_outputs/query_execution/declarative_macro_missing.snap index 748f254f..f68d5348 100644 --- a/test_outputs/query_execution/declarative_macro_missing.snap +++ b/test_outputs/query_execution/declarative_macro_missing.snap @@ -1,6 +1,7 @@ --- source: src/query.rs expression: "&query_execution_results" +snapshot_kind: text --- { "./test_crates/declarative_macro_missing/": [ @@ -9,10 +10,5 @@ expression: "&query_execution_results" "span_begin_line": Uint64(2), "span_filename": String("src/lib.rs"), }, - { - "name": String("will_no_longer_be_exported"), - "span_begin_line": Uint64(7), - "span_filename": String("src/lib.rs"), - }, ], } diff --git a/test_outputs/query_execution/macro_now_doc_hidden.snap b/test_outputs/query_execution/macro_now_doc_hidden.snap new file mode 100644 index 00000000..a84ff171 --- /dev/null +++ b/test_outputs/query_execution/macro_now_doc_hidden.snap @@ -0,0 +1,21 @@ +--- +source: src/query.rs +expression: "&query_execution_results" +snapshot_kind: text +--- +{ + "./test_crates/declarative_macro_missing/": [ + { + "name": String("became_doc_hidden"), + "span_begin_line": Uint64(7), + "span_filename": String("src/lib.rs"), + }, + ], + "./test_crates/macro_now_doc_hidden/": [ + { + "name": String("will_be_hidden"), + "span_begin_line": Uint64(4), + "span_filename": String("src/lib.rs"), + }, + ], +}