diff --git a/src/lints/inherent_method_must_use_added.ron b/src/lints/inherent_method_must_use_added.ron new file mode 100644 index 00000000..aa4bdf88 --- /dev/null +++ b/src/lints/inherent_method_must_use_added.ron @@ -0,0 +1,80 @@ +SemverQuery( + id: "inherent_method_must_use_added", + human_readable_name: "inherent method #[must_use] added", + description: "An inherent method 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 { + current { + item { + ... on ImplOwner { + visibility_limit @filter(op: "=", value: ["$public"]) @output + name @tag @output + owner_type: __typename @tag @output + + importable_path { + path @tag @output + } + + inherent_impl { + method { + method_visibility: visibility_limit @filter(op: "=", value: ["$public"]) @output + method_name: name @tag @output + + attribute { + new_attr: raw_attribute @output + content { + base @filter(op: "=", value: ["$must_use"]) + } + } + + span_: span @optional { + filename @output + begin_line @output + } + } + } + } + } + } + baseline { + item { + ... on ImplOwner { + visibility_limit @filter(op: "=", value: ["$public"]) + name @filter(op: "=", value: ["%name"]) + __typename @filter(op: "=", value: ["%owner_type"]) + + importable_path { + path @filter(op: "=", value: ["%path"]) + } + + inherent_impl { + method { + visibility_limit @filter(op: "=", value: ["$public"]) + name @filter(op: "=", value: ["%method_name"]) + + attribute @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { + content { + base @filter(op: "=", value: ["$must_use"]) + } + } + } + } + } + } + } + } + }"#, + arguments: { + "public": "public", + "must_use": "must_use", + "zero": 0, + }, + error_message: "An inherent method is now #[must_use]. Downstream crates that did not use its return value will get a compiler lint.", + per_result_error_template: Some("method {{join \"::\" path}}::{{method_name}} in {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index 45041b9a..99b7524c 100644 --- a/src/query.rs +++ b/src/query.rs @@ -424,6 +424,7 @@ add_lints!( function_unsafe_added, inherent_method_const_removed, inherent_method_missing, + inherent_method_must_use_added, inherent_method_unsafe_added, method_parameter_count_changed, sized_impl_removed, diff --git a/test_crates/inherent_method_must_use_added/new/Cargo.toml b/test_crates/inherent_method_must_use_added/new/Cargo.toml new file mode 100644 index 00000000..2119cdf6 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/new/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "inherent_method_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/inherent_method_must_use_added/new/src/enum_inherent_method_must_use_added.rs b/test_crates/inherent_method_must_use_added/new/src/enum_inherent_method_must_use_added.rs new file mode 100644 index 00000000..d1f87bd2 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/new/src/enum_inherent_method_must_use_added.rs @@ -0,0 +1,82 @@ +pub enum EnumWithMustUseMethods { + Bar, +} + +impl EnumWithMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + + // These methods 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. + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +// This public enum's inherent method did not have the #[must_use] attribute +// in the old version. Because the method is private, adding the attribute +// should NOT be reported. + +pub enum EnumWithPrivateMustUseMethods { + Bar, +} + +impl EnumWithPrivateMustUseMethods { + + #[must_use] + fn PrivateMethodToPrivateMustUseMethod(&self) {} +} + + +// This enum is private and adding #[must_use] to its inherent method +// should NOT be reported. + +enum PrivateEnumWithMustUseMethods { + Bar, +} + +impl PrivateEnumWithMustUseMethods { + + #[must_use] + fn PrivateEnumMethodToPrivateEnumMustUseMethod(&self) {} +} + + +// This enum and its inherent method were added in the new version of the +// crate, together with the method's 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. + +pub enum NewEnumWithMustUseMethods { + Bar, +} + +impl NewEnumWithMustUseMethods { + + #[must_use] + pub fn NewEnumMustUseMethod(&self) {} +} diff --git a/test_crates/inherent_method_must_use_added/new/src/item_type_changed_inherent_method_must_use_added.rs b/test_crates/inherent_method_must_use_added/new/src/item_type_changed_inherent_method_must_use_added.rs new file mode 100644 index 00000000..112ab098 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/new/src/item_type_changed_inherent_method_must_use_added.rs @@ -0,0 +1,163 @@ +// This test file pair contains test cases against items changing the type +// between the old and new versions while their names and inherent methods +// remain unchanged. +// This can result in false-positives by reporting an addition of #[must_use] +// to an inherent method while the ImplOwner of the method has changed, making +// the new version method no more related to the old version method. + +pub struct EnumToStructWithMustUseMethods {} + +impl EnumToStructWithMustUseMethods { + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub union EnumToUnionWithMustUseMethods { + bar: usize, +} + +impl EnumToUnionWithMustUseMethods { + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub enum StructToEnumWithMustUseMethods { + Bar, +} + +impl StructToEnumWithMustUseMethods { + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub union StructToUnionWithMustUseMethods { + bar: usize, +} + +impl StructToUnionWithMustUseMethods { + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub enum UnionToEnumWithMustUseMethods { + Bar, +} + +impl UnionToEnumWithMustUseMethods { + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub struct UnionToStructWithMustUseMethods {} + +impl UnionToStructWithMustUseMethods { + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} diff --git a/test_crates/inherent_method_must_use_added/new/src/lib.rs b/test_crates/inherent_method_must_use_added/new/src/lib.rs new file mode 100644 index 00000000..0a151612 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/new/src/lib.rs @@ -0,0 +1,10 @@ +// This crate's test cases were separated into smaller files for easier +// management and debugging. + +pub mod enum_inherent_method_must_use_added; + +pub mod struct_inherent_method_must_use_added; + +pub mod union_inherent_method_must_use_added; + +pub mod item_type_changed_inherent_method_must_use_added; diff --git a/test_crates/inherent_method_must_use_added/new/src/struct_inherent_method_must_use_added.rs b/test_crates/inherent_method_must_use_added/new/src/struct_inherent_method_must_use_added.rs new file mode 100644 index 00000000..cad907de --- /dev/null +++ b/test_crates/inherent_method_must_use_added/new/src/struct_inherent_method_must_use_added.rs @@ -0,0 +1,74 @@ +pub struct StructWithMustUseMethods {} + +impl StructWithMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + + // These methods 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. + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +// This public struct's inherent method did not have the #[must_use] attribute +// in the old version. Because the method is private, adding the attribute +// should NOT be reported. + +pub struct StructWithPrivateMustUseMethods {} + +impl StructWithPrivateMustUseMethods { + + #[must_use] + fn PrivateMethodToPrivateMustUseMethod(&self) {} +} + + +// This struct is private and adding #[must_use] to its inherent method +// should NOT be reported. + +struct PrivateStructWithMustUseMethods {} + +impl PrivateStructWithMustUseMethods { + + #[must_use] + fn PrivateStructMethodToPrivateStructMustUseMethod(&self) {} +} + + +// This struct and its inherent method were added in the new version of the +// crate, together with the method's 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. + +pub struct NewStructWithMustUseMethods {} + +impl NewStructWithMustUseMethods { + + #[must_use] + pub fn NewStructMustUseMethod(&self) {} +} diff --git a/test_crates/inherent_method_must_use_added/new/src/union_inherent_method_must_use_added.rs b/test_crates/inherent_method_must_use_added/new/src/union_inherent_method_must_use_added.rs new file mode 100644 index 00000000..94083ac0 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/new/src/union_inherent_method_must_use_added.rs @@ -0,0 +1,82 @@ +pub union UnionWithMustUseMethods { + bar: usize, +} + +impl UnionWithMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + #[must_use] + pub fn MethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MethodToMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + pub fn MustUseMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + + // These methods 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. + + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Baz"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +// This public union's inherent method did not have the #[must_use] attribute +// in the old version. Because the method is private, adding the attribute +// should NOT be reported. + +pub union UnionWithPrivateMustUseMethods { + bar: usize, +} + +impl UnionWithPrivateMustUseMethods { + + #[must_use] + fn PrivateMethodToPrivateMustUseMethod(&self) {} +} + + +// This union is private and adding #[must_use] to its inherent method +// should NOT be reported. + +union PrivateUnionWithMustUseMethods { + bar: usize, +} + +impl PrivateUnionWithMustUseMethods { + + #[must_use] + fn PrivateUnionMethodToPrivateUnionMustUseMethod(&self) {} +} + + +// This union and its inherent method were added in the new version of the +// crate, together with the method's 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. + +pub union NewUnionWithMustUseMethods { + bar: usize, +} + +impl NewUnionWithMustUseMethods { + + #[must_use] + pub fn NewUnionMustUseMethod(&self) {} +} diff --git a/test_crates/inherent_method_must_use_added/old/Cargo.toml b/test_crates/inherent_method_must_use_added/old/Cargo.toml new file mode 100644 index 00000000..2119cdf6 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/old/Cargo.toml @@ -0,0 +1,7 @@ +[package] +publish = false +name = "inherent_method_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/inherent_method_must_use_added/old/src/enum_inherent_method_must_use_added.rs b/test_crates/inherent_method_must_use_added/old/src/enum_inherent_method_must_use_added.rs new file mode 100644 index 00000000..64c7386f --- /dev/null +++ b/test_crates/inherent_method_must_use_added/old/src/enum_inherent_method_must_use_added.rs @@ -0,0 +1,64 @@ +pub enum EnumWithMustUseMethods { + Bar, +} + +impl EnumWithMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes + // of the attribute, including deletion, should not be reported. + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + + // These methods 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. + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +// This public enum's inherent method did not have the #[must_use] attribute +// in the old version. Because the method is private, adding the attribute +// should NOT be reported. + +pub enum EnumWithPrivateMustUseMethods { + Bar, +} + +impl EnumWithPrivateMustUseMethods { + + fn PrivateMethodToPrivateMustUseMethod(&self) {} +} + + +// This enum is private and adding #[must_use] to its inherent method +// should NOT be reported. + +enum PrivateEnumWithMustUseMethods { + Bar, +} + +impl PrivateEnumWithMustUseMethods { + + fn PrivateEnumMethodToPrivateEnumMustUseMethod(&self) {} +} diff --git a/test_crates/inherent_method_must_use_added/old/src/item_type_changed_inherent_method_must_use_added.rs b/test_crates/inherent_method_must_use_added/old/src/item_type_changed_inherent_method_must_use_added.rs new file mode 100644 index 00000000..6122d9ec --- /dev/null +++ b/test_crates/inherent_method_must_use_added/old/src/item_type_changed_inherent_method_must_use_added.rs @@ -0,0 +1,163 @@ +// This test file pair contains test cases against items changing the type +// between the old and new versions while their names and inherent methods +// remain unchanged. +// This can result in false-positives by reporting an addition of #[must_use] +// to an inherent method while the ImplOwner of the method has changed, making +// the new version method no more related to the old version method. + +pub enum EnumToStructWithMustUseMethods { + Bar, +} + +impl EnumToStructWithMustUseMethods { + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub enum EnumToUnionWithMustUseMethods { + Bar, +} + +impl EnumToUnionWithMustUseMethods { + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub struct StructToEnumWithMustUseMethods {} + +impl StructToEnumWithMustUseMethods { + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub struct StructToUnionWithMustUseMethods {} + +impl StructToUnionWithMustUseMethods { + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub union UnionToEnumWithMustUseMethods { + bar: usize, +} + +impl UnionToEnumWithMustUseMethods { + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +pub union UnionToStructWithMustUseMethods { + bar: usize, +} + +impl UnionToStructWithMustUseMethods { + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} diff --git a/test_crates/inherent_method_must_use_added/old/src/lib.rs b/test_crates/inherent_method_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..0a151612 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/old/src/lib.rs @@ -0,0 +1,10 @@ +// This crate's test cases were separated into smaller files for easier +// management and debugging. + +pub mod enum_inherent_method_must_use_added; + +pub mod struct_inherent_method_must_use_added; + +pub mod union_inherent_method_must_use_added; + +pub mod item_type_changed_inherent_method_must_use_added; diff --git a/test_crates/inherent_method_must_use_added/old/src/struct_inherent_method_must_use_added.rs b/test_crates/inherent_method_must_use_added/old/src/struct_inherent_method_must_use_added.rs new file mode 100644 index 00000000..c0bd7dd9 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/old/src/struct_inherent_method_must_use_added.rs @@ -0,0 +1,58 @@ +pub struct StructWithMustUseMethods {} + +impl StructWithMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes + // of the attribute, including deletion, should not be reported. + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + + // These methods 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. + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +// This public struct's inherent method did not have the #[must_use] attribute +// in the old version. Because the method is private, adding the attribute +// should NOT be reported. + +pub struct StructWithPrivateMustUseMethods {} + +impl StructWithPrivateMustUseMethods { + + fn PrivateMethodToPrivateMustUseMethod(&self) {} +} + + +// This struct is private and adding #[must_use] to its inherent method +// should NOT be reported. + +struct PrivateStructWithMustUseMethods {} + +impl PrivateStructWithMustUseMethods { + + fn PrivateStructMethodToPrivateStructMustUseMethod(&self) {} +} diff --git a/test_crates/inherent_method_must_use_added/old/src/union_inherent_method_must_use_added.rs b/test_crates/inherent_method_must_use_added/old/src/union_inherent_method_must_use_added.rs new file mode 100644 index 00000000..987c7514 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/old/src/union_inherent_method_must_use_added.rs @@ -0,0 +1,64 @@ +pub union UnionWithMustUseMethods { + bar: usize, +} + +impl UnionWithMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + pub fn MethodToMustUseMethod(&self) {} + + pub fn MethodToMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes + // of the attribute, including deletion, should not be reported. + + #[must_use] + pub fn MustUseMethodToMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMustUseMessageMethod(&self) {} + + + // These methods 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. + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMustUseMessageMethod(&self) {} +} + + +// This public union's inherent method did not have the #[must_use] attribute +// in the old version. Because the method is private, adding the attribute +// should NOT be reported. + +pub union UnionWithPrivateMustUseMethods { + bar: usize, +} + +impl UnionWithPrivateMustUseMethods { + + fn PrivateMethodToPrivateMustUseMethod(&self) {} +} + + +// This union is private and adding #[must_use] to its inherent method +// should NOT be reported. + +union PrivateUnionWithMustUseMethods { + bar: usize, +} + +impl PrivateUnionWithMustUseMethods { + + fn PrivateUnionMethodToPrivateUnionMustUseMethod(&self) {} +} diff --git a/test_outputs/enum_missing.output.ron b/test_outputs/enum_missing.output.ron index 5a94813c..c9c795e2 100644 --- a/test_outputs/enum_missing.output.ron +++ b/test_outputs/enum_missing.output.ron @@ -33,4 +33,28 @@ "visibility_limit": String("public"), }, ], + "./test_crates/inherent_method_must_use_added/": [ + { + "name": String("EnumToStructWithMustUseMethods"), + "path": List([ + String("inherent_method_must_use_added"), + String("item_type_changed_inherent_method_must_use_added"), + String("EnumToStructWithMustUseMethods"), + ]), + "span_begin_line": Uint64(8), + "span_filename": String("src/item_type_changed_inherent_method_must_use_added.rs"), + "visibility_limit": String("public"), + }, + { + "name": String("EnumToUnionWithMustUseMethods"), + "path": List([ + String("inherent_method_must_use_added"), + String("item_type_changed_inherent_method_must_use_added"), + String("EnumToUnionWithMustUseMethods"), + ]), + "span_begin_line": Uint64(35), + "span_filename": String("src/item_type_changed_inherent_method_must_use_added.rs"), + "visibility_limit": String("public"), + }, + ], } diff --git a/test_outputs/inherent_method_must_use_added.output.ron b/test_outputs/inherent_method_must_use_added.output.ron new file mode 100644 index 00000000..3bdeda72 --- /dev/null +++ b/test_outputs/inherent_method_must_use_added.output.ron @@ -0,0 +1,64 @@ +{ + "./test_crates/inherent_method_must_use_added/": [ + { + "method_name": String("MethodToMustUseMethod"), + "method_visibility": String("public"), + "name": String("EnumWithMustUseMethods"), + "new_attr": String("#[must_use]"), + "owner_type": String("Enum"), + "path": List([ + String("inherent_method_must_use_added"), + String("enum_inherent_method_must_use_added"), + String("EnumWithMustUseMethods"), + ]), + "span_begin_line": Uint64(11), + "span_filename": String("src/enum_inherent_method_must_use_added.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("MethodToMustUseMessageMethod"), + "method_visibility": String("public"), + "name": String("EnumWithMustUseMethods"), + "new_attr": String("#[must_use = \"Foo\"]"), + "owner_type": String("Enum"), + "path": List([ + String("inherent_method_must_use_added"), + String("enum_inherent_method_must_use_added"), + String("EnumWithMustUseMethods"), + ]), + "span_begin_line": Uint64(14), + "span_filename": String("src/enum_inherent_method_must_use_added.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("MethodToMustUseMethod"), + "method_visibility": String("public"), + "name": String("StructWithMustUseMethods"), + "new_attr": String("#[must_use]"), + "owner_type": String("Struct"), + "path": List([ + String("inherent_method_must_use_added"), + String("struct_inherent_method_must_use_added"), + String("StructWithMustUseMethods"), + ]), + "span_begin_line": Uint64(9), + "span_filename": String("src/struct_inherent_method_must_use_added.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("MethodToMustUseMessageMethod"), + "method_visibility": String("public"), + "name": String("StructWithMustUseMethods"), + "new_attr": String("#[must_use = \"Foo\"]"), + "owner_type": String("Struct"), + "path": List([ + String("inherent_method_must_use_added"), + String("struct_inherent_method_must_use_added"), + String("StructWithMustUseMethods"), + ]), + "span_begin_line": Uint64(12), + "span_filename": String("src/struct_inherent_method_must_use_added.rs"), + "visibility_limit": String("public"), + }, + ], +} diff --git a/test_outputs/struct_missing.output.ron b/test_outputs/struct_missing.output.ron index 6e7e9a18..8a380cdb 100644 --- a/test_outputs/struct_missing.output.ron +++ b/test_outputs/struct_missing.output.ron @@ -1,4 +1,30 @@ { + "./test_crates/inherent_method_must_use_added/": [ + { + "name": String("StructToEnumWithMustUseMethods"), + "path": List([ + String("inherent_method_must_use_added"), + String("item_type_changed_inherent_method_must_use_added"), + String("StructToEnumWithMustUseMethods"), + ]), + "span_begin_line": Uint64(62), + "span_filename": String("src/item_type_changed_inherent_method_must_use_added.rs"), + "struct_type": String("plain"), + "visibility_limit": String("public"), + }, + { + "name": String("StructToUnionWithMustUseMethods"), + "path": List([ + String("inherent_method_must_use_added"), + String("item_type_changed_inherent_method_must_use_added"), + String("StructToUnionWithMustUseMethods"), + ]), + "span_begin_line": Uint64(87), + "span_filename": String("src/item_type_changed_inherent_method_must_use_added.rs"), + "struct_type": String("plain"), + "visibility_limit": String("public"), + }, + ], "./test_crates/struct_missing/": [ { "name": String("WillBeRemovedStruct"),