diff --git a/src/lints/inherent_method_now_doc_hidden.ron b/src/lints/inherent_method_now_doc_hidden.ron new file mode 100644 index 00000000..156c285c --- /dev/null +++ b/src/lints/inherent_method_now_doc_hidden.ron @@ -0,0 +1,65 @@ +SemverQuery( + id: "inherent_method_now_doc_hidden", + human_readable_name: "inherent method #[doc(hidden)] added", + description: "A method or associated fn is now marked #[doc(hidden)] and is thus no longer part of the public API.", + 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 ImplOwner { + visibility_limit @filter(op: "=", value: ["$public"]) @output + + importable_path { + path @output @tag + public_api @filter(op: "=", value: ["$true"]) + } + + inherent_impl { + method { + method_visibility: visibility_limit @filter(op: "=", value: ["$public"]) @output + method_name: name @output @tag + public_api_eligible @filter(op: "=", value: ["$true"]) + + span_: span @optional { + filename @output + begin_line @output + } + } + } + } + } + } + current { + item { + ... on ImplOwner { + visibility_limit @filter(op: "=", value: ["$public"]) + name @output + + importable_path { + path @filter(op: "=", value: ["%path"]) + public_api @filter(op: "=", value: ["$true"]) + } + + inherent_impl { + method { + method_visibility: visibility_limit @filter(op: "=", value: ["$public"]) + name @filter(op: "=", value: ["%method_name"]) + public_api_eligible @filter(op: "!=", value: ["$true"]) + } + } + } + } + } + } + }"#, + arguments: { + "public": "public", + "true": true + }, + error_message: "A method or associated fn is now #[doc(hidden)], removing it from the crate's public API.", + per_result_error_template: Some("{{name}}::{{method_name}} in file {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index 4076c193..7463121b 100644 --- a/src/query.rs +++ b/src/query.rs @@ -762,6 +762,7 @@ add_lints!( inherent_method_const_removed, inherent_method_missing, inherent_method_must_use_added, + inherent_method_now_doc_hidden, inherent_method_unsafe_added, method_parameter_count_changed, module_missing, diff --git a/test_crates/inherent_method_now_doc_hidden/new/Cargo.toml b/test_crates/inherent_method_now_doc_hidden/new/Cargo.toml new file mode 100644 index 00000000..cb789584 --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/new/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "inherent_method_now_doc_hidden" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/inherent_method_now_doc_hidden/new/src/doc_hidden_struct_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/new/src/doc_hidden_struct_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..a9162ca9 --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/new/src/doc_hidden_struct_inherent_method_now_doc_hidden.rs @@ -0,0 +1,17 @@ +// Tests false positives. If the struct is #[doc(hidden)], changing hidden state of methods should +// have no effect. + +#[doc(hidden)] +pub struct Foo; + +impl Foo { + #[doc(hidden)] + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + #[doc(hidden)] + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/new/src/enum_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/new/src/enum_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..2c25097f --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/new/src/enum_inherent_method_now_doc_hidden.rs @@ -0,0 +1,15 @@ +pub enum Foo { + Bar, +} + +impl Foo { + #[doc(hidden)] + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + #[doc(hidden)] + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/new/src/lib.rs b/test_crates/inherent_method_now_doc_hidden/new/src/lib.rs new file mode 100644 index 00000000..1ed7527b --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/new/src/lib.rs @@ -0,0 +1,10 @@ + +pub mod union_inherent_method_now_doc_hidden; + +pub mod enum_inherent_method_now_doc_hidden; + +pub mod struct_inherent_method_now_doc_hidden; + +pub mod doc_hidden_struct_inherent_method_now_doc_hidden; + +pub mod struct_and_inherent_method_now_doc_hidden; diff --git a/test_crates/inherent_method_now_doc_hidden/new/src/struct_and_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/new/src/struct_and_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..94967bfa --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/new/src/struct_and_inherent_method_now_doc_hidden.rs @@ -0,0 +1,17 @@ +// Tests false positives. If the struct becomes #[doc(hidden)], it should trigger +// struct_now_doc_hidden, and changing hidden state of methods should have no further effect. + +#[doc(hidden)] +pub struct Foo; + +impl Foo { + #[doc(hidden)] + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + #[doc(hidden)] + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/new/src/struct_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/new/src/struct_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..b7bf1fe3 --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/new/src/struct_inherent_method_now_doc_hidden.rs @@ -0,0 +1,13 @@ +pub struct Foo; + +impl Foo { + #[doc(hidden)] + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + #[doc(hidden)] + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/new/src/union_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/new/src/union_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..6604ddb4 --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/new/src/union_inherent_method_now_doc_hidden.rs @@ -0,0 +1,16 @@ +pub union Foo { + f1: u32, + f2: f32, +} + +impl Foo { + #[doc(hidden)] + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + #[doc(hidden)] + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/old/Cargo.toml b/test_crates/inherent_method_now_doc_hidden/old/Cargo.toml new file mode 100644 index 00000000..cb789584 --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/old/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "inherent_method_now_doc_hidden" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/inherent_method_now_doc_hidden/old/src/doc_hidden_struct_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/old/src/doc_hidden_struct_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..5a9d3139 --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/old/src/doc_hidden_struct_inherent_method_now_doc_hidden.rs @@ -0,0 +1,15 @@ +// Tests false positives. If the struct is #[doc(hidden)], changing hidden state of methods should +// have no effect. + +#[doc(hidden)] +pub struct Foo; + +impl Foo { + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/old/src/enum_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/old/src/enum_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..135ce7f0 --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/old/src/enum_inherent_method_now_doc_hidden.rs @@ -0,0 +1,13 @@ +pub enum Foo { + Bar, +} + +impl Foo { + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/old/src/lib.rs b/test_crates/inherent_method_now_doc_hidden/old/src/lib.rs new file mode 100644 index 00000000..1ed7527b --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/old/src/lib.rs @@ -0,0 +1,10 @@ + +pub mod union_inherent_method_now_doc_hidden; + +pub mod enum_inherent_method_now_doc_hidden; + +pub mod struct_inherent_method_now_doc_hidden; + +pub mod doc_hidden_struct_inherent_method_now_doc_hidden; + +pub mod struct_and_inherent_method_now_doc_hidden; diff --git a/test_crates/inherent_method_now_doc_hidden/old/src/struct_and_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/old/src/struct_and_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..1edf9bb5 --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/old/src/struct_and_inherent_method_now_doc_hidden.rs @@ -0,0 +1,14 @@ +// Tests false positives. If the struct becomes #[doc(hidden)], it should trigger +// struct_now_doc_hidden, and changing hidden state of methods should have no further effect. + +pub struct Foo; + +impl Foo { + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/old/src/struct_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/old/src/struct_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..b9f14bef --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/old/src/struct_inherent_method_now_doc_hidden.rs @@ -0,0 +1,11 @@ +pub struct Foo; + +impl Foo { + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_crates/inherent_method_now_doc_hidden/old/src/union_inherent_method_now_doc_hidden.rs b/test_crates/inherent_method_now_doc_hidden/old/src/union_inherent_method_now_doc_hidden.rs new file mode 100644 index 00000000..75897c9e --- /dev/null +++ b/test_crates/inherent_method_now_doc_hidden/old/src/union_inherent_method_now_doc_hidden.rs @@ -0,0 +1,14 @@ +pub union Foo { + f1: u32, + f2: f32, +} + +impl Foo { + pub fn associated_fn(x: i64, y: i64) -> i64 { + x + y + } + + pub fn method(&self, x: i64) -> i64 { + x + } +} diff --git a/test_outputs/inherent_method_now_doc_hidden.output.ron b/test_outputs/inherent_method_now_doc_hidden.output.ron new file mode 100644 index 00000000..0795ec83 --- /dev/null +++ b/test_outputs/inherent_method_now_doc_hidden.output.ron @@ -0,0 +1,82 @@ +{ + "./test_crates/inherent_method_now_doc_hidden/": [ + { + "method_name": String("associated_fn"), + "method_visibility": String("public"), + "name": String("Foo"), + "path": List([ + String("inherent_method_now_doc_hidden"), + String("enum_inherent_method_now_doc_hidden"), + String("Foo"), + ]), + "span_begin_line": Uint64(6), + "span_filename": String("src/enum_inherent_method_now_doc_hidden.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("method"), + "method_visibility": String("public"), + "name": String("Foo"), + "path": List([ + String("inherent_method_now_doc_hidden"), + String("enum_inherent_method_now_doc_hidden"), + String("Foo"), + ]), + "span_begin_line": Uint64(10), + "span_filename": String("src/enum_inherent_method_now_doc_hidden.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("associated_fn"), + "method_visibility": String("public"), + "name": String("Foo"), + "path": List([ + String("inherent_method_now_doc_hidden"), + String("struct_inherent_method_now_doc_hidden"), + String("Foo"), + ]), + "span_begin_line": Uint64(4), + "span_filename": String("src/struct_inherent_method_now_doc_hidden.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("method"), + "method_visibility": String("public"), + "name": String("Foo"), + "path": List([ + String("inherent_method_now_doc_hidden"), + String("struct_inherent_method_now_doc_hidden"), + String("Foo"), + ]), + "span_begin_line": Uint64(8), + "span_filename": String("src/struct_inherent_method_now_doc_hidden.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("associated_fn"), + "method_visibility": String("public"), + "name": String("Foo"), + "path": List([ + String("inherent_method_now_doc_hidden"), + String("union_inherent_method_now_doc_hidden"), + String("Foo"), + ]), + "span_begin_line": Uint64(7), + "span_filename": String("src/union_inherent_method_now_doc_hidden.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("method"), + "method_visibility": String("public"), + "name": String("Foo"), + "path": List([ + String("inherent_method_now_doc_hidden"), + String("union_inherent_method_now_doc_hidden"), + String("Foo"), + ]), + "span_begin_line": Uint64(11), + "span_filename": String("src/union_inherent_method_now_doc_hidden.rs"), + "visibility_limit": String("public"), + }, + ], +} diff --git a/test_outputs/struct_now_doc_hidden.output.ron b/test_outputs/struct_now_doc_hidden.output.ron index 8b717472..32d4e6ff 100644 --- a/test_outputs/struct_now_doc_hidden.output.ron +++ b/test_outputs/struct_now_doc_hidden.output.ron @@ -10,6 +10,18 @@ "struct_name": String("StructF"), }, ], + "./test_crates/inherent_method_now_doc_hidden/": [ + { + "path": List([ + String("inherent_method_now_doc_hidden"), + String("struct_and_inherent_method_now_doc_hidden"), + String("Foo"), + ]), + "span_begin_line": Uint64(5), + "span_filename": String("src/struct_and_inherent_method_now_doc_hidden.rs"), + "struct_name": String("Foo"), + }, + ], "./test_crates/struct_now_doc_hidden/": [ { "path": List([