diff --git a/src/lints/enum_must_use_added.ron b/src/lints/enum_must_use_added.ron new file mode 100644 index 00000000..8b98a96f --- /dev/null +++ b/src/lints/enum_must_use_added.ron @@ -0,0 +1,64 @@ +SemverQuery( + id: "enum_must_use_added", + human_readable_name: "enum #[must_use] added", + description: "An enum has been marked with #[must_use].", + required_update: Minor, + + // TODO: Change the reference link to point to the cargo semver reference + // once it has a section on attribute #[must_use]. + reference_link: Some("https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"), + query: r#" + { + CrateDiff { + baseline { + item { + ... on Enum { + visibility_limit @filter(op: "=", value: ["$public"]) @output + name @tag @output + + importable_path { + path @tag @output + } + + attribute @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { + content { + base @filter(op: "=", value: ["$must_use"]) + } + } + } + } + } + current { + item { + ... on Enum { + visibility_limit @filter(op: "=", value: ["$public"]) + name @filter(op: "=", value: ["%name"]) + + importable_path { + path @filter(op: "=", value: ["%path"]) + } + + attribute { + new_attr: raw_attribute @output + content { + base @filter(op: "=", value: ["$must_use"]) + } + } + + span_: span @optional { + filename @output + begin_line @output + } + } + } + } + } + }"#, + arguments: { + "public": "public", + "must_use": "must_use", + "zero": 0, + }, + error_message: "An enum is now #[must_use]. Downstream crates that did not use its value will get a compiler lint.", + per_result_error_template: Some("enum {{name}} in {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index 9816aeee..1931eb5b 100644 --- a/src/query.rs +++ b/src/query.rs @@ -409,6 +409,7 @@ add_lints!( derive_trait_impl_removed, enum_marked_non_exhaustive, enum_missing, + enum_must_use_added, enum_repr_c_removed, enum_repr_int_changed, enum_repr_int_removed, diff --git a/test_crates/enum_must_use_added/new/Cargo.toml b/test_crates/enum_must_use_added/new/Cargo.toml new file mode 100644 index 00000000..6a362d66 --- /dev/null +++ b/test_crates/enum_must_use_added/new/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enum_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/enum_must_use_added/new/src/lib.rs b/test_crates/enum_must_use_added/new/src/lib.rs new file mode 100644 index 00000000..3423bf1b --- /dev/null +++ b/test_crates/enum_must_use_added/new/src/lib.rs @@ -0,0 +1,62 @@ +// These enums did not have the #[must_use] attribute in the old version. +// Addition of the attribute should be reported by this rule. + +#[must_use] +pub enum EnumToMustUseEnum { + Bar, +} + +#[must_use = "Foo"] +pub enum EnumToMustUseMessageEnum { + Bar, +} + + +// These enums had the #[must_use] attribute in the old version. Changes of +// the attribute, including deletion, should NOT be reported by this rule. + +pub enum MustUseEnumToEnum { + Bar, +} + +#[must_use = "Foo"] +pub enum MustUseEnumToMustUseMessageEnum { + Bar, +} + + +// These enums had the #[must_use] attribute in the old version. +// They also included the user-defined warning message. Changes of +// the attribute, including deletion, should NOT be reported by this rule. + +pub enum MustUseMessageEnumToEnum { + Bar, +} + +#[must_use] +pub enum MustUseMessageEnumToMustUseEnum { + Bar, +} + +#[must_use = "Baz"] +pub enum MustUseMessageEnumToMustUseMessageEnum { + Bar, +} + + +// This enum is private and should NOT be reported by this rule. + +#[must_use] +enum MustUsePrivateEnum { + Bar, +} + + +// This enum was added in the new version of the crate with its attribute. +// It should NOT be reported by this rule to avoid duplicate lints. +// It should be reported as a new pub type that is part of the crate's API. + +#[must_use] +pub enum MustUseNewEnum { + Bar, +} diff --git a/test_crates/enum_must_use_added/old/Cargo.toml b/test_crates/enum_must_use_added/old/Cargo.toml new file mode 100644 index 00000000..6a362d66 --- /dev/null +++ b/test_crates/enum_must_use_added/old/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enum_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/enum_must_use_added/old/src/lib.rs b/test_crates/enum_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..c27a2965 --- /dev/null +++ b/test_crates/enum_must_use_added/old/src/lib.rs @@ -0,0 +1,51 @@ +// These enums did not have the #[must_use] attribute in the old version. +// Addition of the attribute should be reported by this rule. + +pub enum EnumToMustUseEnum { + Bar, +} + +pub enum EnumToMustUseMessageEnum { + Bar, +} + + +// These enums had the #[must_use] attribute in the old version. Changes of +// the attribute, including deletion, should NOT be reported by this rule. + +#[must_use] +pub enum MustUseEnumToEnum { + Bar, +} + +#[must_use] +pub enum MustUseEnumToMustUseMessageEnum { + Bar, +} + + +// These enums had the #[must_use] attribute in the old version. +// They also included the user-defined warning message. Changes of +// the attribute, including deletion, should NOT be reported by this rule. + +#[must_use = "Foo"] +pub enum MustUseMessageEnumToEnum { + Bar, +} + +#[must_use = "Foo"] +pub enum MustUseMessageEnumToMustUseEnum { + Bar, +} + +#[must_use = "Foo"] +pub enum MustUseMessageEnumToMustUseMessageEnum { + Bar, +} + + +// This enum is private and should NOT be reported by this rule. + +enum MustUsePrivateEnum { + Bar, +} diff --git a/test_outputs/enum_must_use_added.output.ron b/test_outputs/enum_must_use_added.output.ron new file mode 100644 index 00000000..5a0d3ab2 --- /dev/null +++ b/test_outputs/enum_must_use_added.output.ron @@ -0,0 +1,26 @@ +{ + "./test_crates/enum_must_use_added/": [ + { + "name": String("EnumToMustUseEnum"), + "new_attr": String("#[must_use]"), + "path": List([ + String("enum_must_use_added"), + String("EnumToMustUseEnum"), + ]), + "span_begin_line": Uint64(5), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "name": String("EnumToMustUseMessageEnum"), + "new_attr": String("#[must_use = \"Foo\"]"), + "path": List([ + String("enum_must_use_added"), + String("EnumToMustUseMessageEnum"), + ]), + "span_begin_line": Uint64(10), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], +}