From 0290beecbda062653c8575b37b5fbe6db7bd1d05 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Fri, 6 Jan 2023 15:40:19 +0100 Subject: [PATCH 01/18] New lint: enum_must_use_added --- src/lints/enum_must_use_added.ron | 64 +++++++++++++++++++ src/query.rs | 1 + .../enum_must_use_added/new/Cargo.toml | 6 ++ .../enum_must_use_added/new/src/lib.rs | 43 +++++++++++++ .../enum_must_use_added/old/Cargo.toml | 6 ++ .../enum_must_use_added/old/src/lib.rs | 44 +++++++++++++ test_outputs/enum_must_use_added.output.ron | 26 ++++++++ 7 files changed, 190 insertions(+) create mode 100644 src/lints/enum_must_use_added.ron create mode 100644 test_crates/enum_must_use_added/new/Cargo.toml create mode 100644 test_crates/enum_must_use_added/new/src/lib.rs create mode 100644 test_crates/enum_must_use_added/old/Cargo.toml create mode 100644 test_crates/enum_must_use_added/old/src/lib.rs create mode 100644 test_outputs/enum_must_use_added.output.ron diff --git a/src/lints/enum_must_use_added.ron b/src/lints/enum_must_use_added.ron new file mode 100644 index 00000000..225b1578 --- /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 has been marked with #[must_use]. This can cause downstream crates that did not use this enum's value to 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..fa14f905 100644 --- a/src/query.rs +++ b/src/query.rs @@ -436,4 +436,5 @@ add_lints!( tuple_struct_to_plain_struct, unit_struct_changed_kind, variant_marked_non_exhaustive, + enum_must_use_added, ); 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..989bb30d --- /dev/null +++ b/test_crates/enum_must_use_added/new/src/lib.rs @@ -0,0 +1,43 @@ +// 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, +} 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..805fa043 --- /dev/null +++ b/test_crates/enum_must_use_added/old/src/lib.rs @@ -0,0 +1,44 @@ +// 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, +} 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..c7a27e80 --- /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(9), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], +} From df6e4c5969a799feab2eb5902da250c2746e1daa Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk <92160712+SmolSir@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:31:09 +0100 Subject: [PATCH 02/18] Update src/lints/enum_must_use_added.ron Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> --- src/lints/enum_must_use_added.ron | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lints/enum_must_use_added.ron b/src/lints/enum_must_use_added.ron index 225b1578..49a54063 100644 --- a/src/lints/enum_must_use_added.ron +++ b/src/lints/enum_must_use_added.ron @@ -5,7 +5,7 @@ SemverQuery( required_update: Minor, // TODO: Change the reference link to point to the cargo semver reference - // once it has a section on attribute [must_use]. + // 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#" { From c72b6d25ab7ab6280acbf00b92611da2528e542d Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Sat, 7 Jan 2023 18:28:22 +0100 Subject: [PATCH 03/18] Missing newline in enum_must_use_added/new/src/lib.rs --- test_crates/enum_must_use_added/new/src/lib.rs | 1 + test_outputs/enum_must_use_added.output.ron | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test_crates/enum_must_use_added/new/src/lib.rs b/test_crates/enum_must_use_added/new/src/lib.rs index 989bb30d..acf9c967 100644 --- a/test_crates/enum_must_use_added/new/src/lib.rs +++ b/test_crates/enum_must_use_added/new/src/lib.rs @@ -5,6 +5,7 @@ pub enum EnumToMustUseEnum { Bar, } + #[must_use = "Foo"] pub enum EnumToMustUseMessageEnum { Bar, diff --git a/test_outputs/enum_must_use_added.output.ron b/test_outputs/enum_must_use_added.output.ron index c7a27e80..5a0d3ab2 100644 --- a/test_outputs/enum_must_use_added.output.ron +++ b/test_outputs/enum_must_use_added.output.ron @@ -18,7 +18,7 @@ String("enum_must_use_added"), String("EnumToMustUseMessageEnum"), ]), - "span_begin_line": Uint64(9), + "span_begin_line": Uint64(10), "span_filename": String("src/lib.rs"), "visibility_limit": String("public"), }, From 343489287e8c9c2de46001b5b1b7ca7ba918b4a3 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Sat, 7 Jan 2023 18:33:29 +0100 Subject: [PATCH 04/18] New lint: struct_must_use_added --- src/lints/struct_must_use_added.ron | 64 +++++++++++++++++++ src/query.rs | 1 + .../struct_must_use_added/new/Cargo.toml | 6 ++ .../struct_must_use_added/new/src/lib.rs | 44 +++++++++++++ .../struct_must_use_added/old/Cargo.toml | 6 ++ .../struct_must_use_added/old/src/lib.rs | 44 +++++++++++++ test_outputs/struct_must_use_added.output.ron | 26 ++++++++ 7 files changed, 191 insertions(+) create mode 100644 src/lints/struct_must_use_added.ron create mode 100644 test_crates/struct_must_use_added/new/Cargo.toml create mode 100644 test_crates/struct_must_use_added/new/src/lib.rs create mode 100644 test_crates/struct_must_use_added/old/Cargo.toml create mode 100644 test_crates/struct_must_use_added/old/src/lib.rs create mode 100644 test_outputs/struct_must_use_added.output.ron diff --git a/src/lints/struct_must_use_added.ron b/src/lints/struct_must_use_added.ron new file mode 100644 index 00000000..2c244a02 --- /dev/null +++ b/src/lints/struct_must_use_added.ron @@ -0,0 +1,64 @@ +SemverQuery( + id: "struct_must_use_added", + human_readable_name: "struct #[must_use] added", + description: "A struct 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 Struct { + 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 Struct { + 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: "A struct has been marked with #[must_use]. This can cause downstream crates that did not use this struct's value to get a compiler lint.", + per_result_error_template: Some("struct {{name}} in {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index fa14f905..321ab833 100644 --- a/src/query.rs +++ b/src/query.rs @@ -437,4 +437,5 @@ add_lints!( unit_struct_changed_kind, variant_marked_non_exhaustive, enum_must_use_added, + struct_must_use_added, ); diff --git a/test_crates/struct_must_use_added/new/Cargo.toml b/test_crates/struct_must_use_added/new/Cargo.toml new file mode 100644 index 00000000..a2dd5d4c --- /dev/null +++ b/test_crates/struct_must_use_added/new/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "struct_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/struct_must_use_added/new/src/lib.rs b/test_crates/struct_must_use_added/new/src/lib.rs new file mode 100644 index 00000000..72787321 --- /dev/null +++ b/test_crates/struct_must_use_added/new/src/lib.rs @@ -0,0 +1,44 @@ +// These structs did not have the #[must_use] attribute in the old version. +// Addition of the attribute should be reported by this rule. + +#[must_use] +pub struct StructToMustUseStruct { + bar: u64, +} + +#[must_use = "Foo"] +pub struct StructToMustUseMessageStruct { + bar: u64, +} + + +// These structs had the #[must_use] attribute in the old version. Changes of +// the attribute, including deletion, should not be reported by this rule. + +pub struct MustUseStructToStruct { + bar: u64, +} + +#[must_use = "Foo"] +pub struct MustUseStructToMustUseMessageStruct { + bar: u64, +} + + +// These structs 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 struct MustUseMessageStructToStruct { + bar: u64, +} + +#[must_use] +pub struct MustUseMessageStructToMustUseStruct { + bar: u64, +} + +#[must_use = "Baz"] +pub struct MustUseMessageStructToMustUseMessageStruct { + bar: u64, +} diff --git a/test_crates/struct_must_use_added/old/Cargo.toml b/test_crates/struct_must_use_added/old/Cargo.toml new file mode 100644 index 00000000..a2dd5d4c --- /dev/null +++ b/test_crates/struct_must_use_added/old/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "struct_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/struct_must_use_added/old/src/lib.rs b/test_crates/struct_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..4621b2c2 --- /dev/null +++ b/test_crates/struct_must_use_added/old/src/lib.rs @@ -0,0 +1,44 @@ +// These structs did not have the #[must_use] attribute in the old version. +// Addition of the attribute should be reported by this rule. + +pub struct StructToMustUseStruct { + bar: u64, +} + +pub struct StructToMustUseMessageStruct { + bar: u64, +} + + +// These structs 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 struct MustUseStructToStruct { + bar: u64, +} + +#[must_use] +pub struct MustUseStructToMustUseMessageStruct { + bar: u64, +} + + +// These structs 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 struct MustUseMessageStructToStruct { + bar: u64, +} + +#[must_use = "Foo"] +pub struct MustUseMessageStructToMustUseStruct { + bar: u64, +} + +#[must_use = "Foo"] +pub struct MustUseMessageStructToMustUseMessageStruct { + bar: u64, +} diff --git a/test_outputs/struct_must_use_added.output.ron b/test_outputs/struct_must_use_added.output.ron new file mode 100644 index 00000000..575b353a --- /dev/null +++ b/test_outputs/struct_must_use_added.output.ron @@ -0,0 +1,26 @@ +{ + "./test_crates/struct_must_use_added/": [ + { + "name": String("StructToMustUseStruct"), + "new_attr": String("#[must_use]"), + "path": List([ + String("struct_must_use_added"), + String("StructToMustUseStruct"), + ]), + "span_begin_line": Uint64(5), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "name": String("StructToMustUseMessageStruct"), + "new_attr": String("#[must_use = \"Foo\"]"), + "path": List([ + String("struct_must_use_added"), + String("StructToMustUseMessageStruct"), + ]), + "span_begin_line": Uint64(10), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], +} From 36854b4ff84c00c703a0eb01b5b1abaf1ed698ed Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Sat, 7 Jan 2023 19:16:50 +0100 Subject: [PATCH 05/18] New lint: function_must_use_added --- src/lints/function_must_use_added.ron | 64 +++++++++++++++++++ src/query.rs | 1 + .../function_must_use_added/new/Cargo.toml | 6 ++ .../function_must_use_added/new/src/lib.rs | 44 +++++++++++++ .../function_must_use_added/old/Cargo.toml | 6 ++ .../function_must_use_added/old/src/lib.rs | 44 +++++++++++++ .../function_must_use_added.output.ron | 26 ++++++++ 7 files changed, 191 insertions(+) create mode 100644 src/lints/function_must_use_added.ron create mode 100644 test_crates/function_must_use_added/new/Cargo.toml create mode 100644 test_crates/function_must_use_added/new/src/lib.rs create mode 100644 test_crates/function_must_use_added/old/Cargo.toml create mode 100644 test_crates/function_must_use_added/old/src/lib.rs create mode 100644 test_outputs/function_must_use_added.output.ron diff --git a/src/lints/function_must_use_added.ron b/src/lints/function_must_use_added.ron new file mode 100644 index 00000000..5e796d0a --- /dev/null +++ b/src/lints/function_must_use_added.ron @@ -0,0 +1,64 @@ +SemverQuery( + id: "function_must_use_added", + human_readable_name: "function #[must_use] added", + description: "A function 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 Function { + 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 Function { + 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: "A function has been marked with #[must_use]. This can cause downstream crates that did not use the value returned by this function to get a compiler lint.", + per_result_error_template: Some("function {{name}} in {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index 321ab833..ff5344d5 100644 --- a/src/query.rs +++ b/src/query.rs @@ -438,4 +438,5 @@ add_lints!( variant_marked_non_exhaustive, enum_must_use_added, struct_must_use_added, + function_must_use_added, ); diff --git a/test_crates/function_must_use_added/new/Cargo.toml b/test_crates/function_must_use_added/new/Cargo.toml new file mode 100644 index 00000000..58f04aa8 --- /dev/null +++ b/test_crates/function_must_use_added/new/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "function_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/function_must_use_added/new/src/lib.rs b/test_crates/function_must_use_added/new/src/lib.rs new file mode 100644 index 00000000..da993f13 --- /dev/null +++ b/test_crates/function_must_use_added/new/src/lib.rs @@ -0,0 +1,44 @@ +// These functions did not have the #[must_use] attribute in the old version. +// Addition of the attribute should be reported by this rule. + +#[must_use] +pub fn FunctionToMustUseFunction(x: i64) -> i64 { + x +} + +#[must_use = "Foo"] +pub fn FunctionToMustUseMessageFunction(x: i64) -> i64 { + x +} + + +// These functions had the #[must_use] attribute in the old version. Changes of +// the attribute, including deletion, should not be reported by this rule. + +pub fn MustUseFunctionToFunction(x: i64) -> i64 { + x +} + +#[must_use = "Foo"] +pub fn MustUseFunctionToMustUseMessageFunction(x: i64) -> i64 { + x +} + + +// These functions 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 fn MustUseMessageFunctionToFunction(x: i64) -> i64 { + x +} + +#[must_use] +pub fn MustUseMessageFunctionToMustUseFunction(x: i64) -> i64 { + x +} + +#[must_use = "Baz"] +pub fn MustUseMessageFunctionToMustUseMessageFunction(x: i64) -> i64 { + x +} diff --git a/test_crates/function_must_use_added/old/Cargo.toml b/test_crates/function_must_use_added/old/Cargo.toml new file mode 100644 index 00000000..58f04aa8 --- /dev/null +++ b/test_crates/function_must_use_added/old/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "function_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/function_must_use_added/old/src/lib.rs b/test_crates/function_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..528eeb24 --- /dev/null +++ b/test_crates/function_must_use_added/old/src/lib.rs @@ -0,0 +1,44 @@ +// These functions did not have the #[must_use] attribute in the old version. +// Addition of the attribute should be reported by this rule. + +pub fn FunctionToMustUseFunction(x: i64) -> i64 { + x +} + +pub fn FunctionToMustUseMessageFunction(x: i64) -> i64 { + x +} + + +// These functions 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 fn MustUseFunctionToFunction(x: i64) -> i64 { + x +} + +#[must_use] +pub fn MustUseFunctionToMustUseMessageFunction(x: i64) -> i64 { + x +} + + +// These functions 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 fn MustUseMessageFunctionToFunction(x: i64) -> i64 { + x +} + +#[must_use = "Foo"] +pub fn MustUseMessageFunctionToMustUseFunction(x: i64) -> i64 { + x +} + +#[must_use = "Foo"] +pub fn MustUseMessageFunctionToMustUseMessageFunction(x: i64) -> i64 { + x +} diff --git a/test_outputs/function_must_use_added.output.ron b/test_outputs/function_must_use_added.output.ron new file mode 100644 index 00000000..96fe2a07 --- /dev/null +++ b/test_outputs/function_must_use_added.output.ron @@ -0,0 +1,26 @@ +{ + "./test_crates/function_must_use_added/": [ + { + "name": String("FunctionToMustUseFunction"), + "new_attr": String("#[must_use]"), + "path": List([ + String("function_must_use_added"), + String("FunctionToMustUseFunction"), + ]), + "span_begin_line": Uint64(5), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "name": String("FunctionToMustUseMessageFunction"), + "new_attr": String("#[must_use = \"Foo\"]"), + "path": List([ + String("function_must_use_added"), + String("FunctionToMustUseMessageFunction"), + ]), + "span_begin_line": Uint64(10), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], +} From d7929a6865a674b73bfc684168dcd9699ce280d5 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Sat, 7 Jan 2023 19:28:59 +0100 Subject: [PATCH 06/18] Update per_result_error_template in function_must_use_added lint --- src/lints/function_must_use_added.ron | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lints/function_must_use_added.ron b/src/lints/function_must_use_added.ron index 5e796d0a..915b44d3 100644 --- a/src/lints/function_must_use_added.ron +++ b/src/lints/function_must_use_added.ron @@ -60,5 +60,5 @@ SemverQuery( "zero": 0, }, error_message: "A function has been marked with #[must_use]. This can cause downstream crates that did not use the value returned by this function to get a compiler lint.", - per_result_error_template: Some("function {{name}} in {{span_filename}}:{{span_begin_line}}"), + per_result_error_template: Some("function {{join \"::\" path}} in {{span_filename}}:{{span_begin_line}}"), ) From deb3c3211a0122394f7bf65780d23a095c1e07be Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Sat, 7 Jan 2023 19:56:07 +0100 Subject: [PATCH 07/18] New lint: trait_must_use_added --- src/lints/trait_must_use_added.ron | 64 +++++++++++++++++++ src/query.rs | 1 + .../trait_must_use_added/new/Cargo.toml | 6 ++ .../trait_must_use_added/new/src/lib.rs | 30 +++++++++ .../trait_must_use_added/old/Cargo.toml | 6 ++ .../trait_must_use_added/old/src/lib.rs | 30 +++++++++ test_outputs/trait_must_use_added.output.ron | 26 ++++++++ 7 files changed, 163 insertions(+) create mode 100644 src/lints/trait_must_use_added.ron create mode 100644 test_crates/trait_must_use_added/new/Cargo.toml create mode 100644 test_crates/trait_must_use_added/new/src/lib.rs create mode 100644 test_crates/trait_must_use_added/old/Cargo.toml create mode 100644 test_crates/trait_must_use_added/old/src/lib.rs create mode 100644 test_outputs/trait_must_use_added.output.ron diff --git a/src/lints/trait_must_use_added.ron b/src/lints/trait_must_use_added.ron new file mode 100644 index 00000000..1137c8e2 --- /dev/null +++ b/src/lints/trait_must_use_added.ron @@ -0,0 +1,64 @@ +SemverQuery( + id: "trait_must_use_added", + human_readable_name: "trait #[must_use] added", + description: "A trait 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 Trait { + 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 Trait { + 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: "A trait has been marked with #[must_use]. This can cause downstream crates that called a function returning an impl or dyn value of this trait to get a compiler lint.", + per_result_error_template: Some("trait {{join \"::\" path}} in {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index ff5344d5..1f5d9917 100644 --- a/src/query.rs +++ b/src/query.rs @@ -439,4 +439,5 @@ add_lints!( enum_must_use_added, struct_must_use_added, function_must_use_added, + trait_must_use_added, ); diff --git a/test_crates/trait_must_use_added/new/Cargo.toml b/test_crates/trait_must_use_added/new/Cargo.toml new file mode 100644 index 00000000..5965321c --- /dev/null +++ b/test_crates/trait_must_use_added/new/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "trait_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/trait_must_use_added/new/src/lib.rs b/test_crates/trait_must_use_added/new/src/lib.rs new file mode 100644 index 00000000..9bfa4a9c --- /dev/null +++ b/test_crates/trait_must_use_added/new/src/lib.rs @@ -0,0 +1,30 @@ +// These traits did not have the #[must_use] attribute in the old version. +// Addition of the attribute should be reported by this rule. + +#[must_use] +pub trait TraitToMustUseTrait {} + +#[must_use = "Foo"] +pub trait TraitToMustUseMessageTrait {} + + +// These traits had the #[must_use] attribute in the old version. Changes of +// the attribute, including deletion, should not be reported by this rule. + +pub trait MustUseTraitToTrait {} + +#[must_use = "Foo"] +pub trait MustUseTraitToMustUseMessageTrait {} + + +// These traits 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 trait MustUseMessageTraitToTrait {} + +#[must_use] +pub trait MustUseMessageTraitToMustUseTrait {} + +#[must_use = "Baz"] +pub trait MustUseMessageTraitToMustUseMessageTrait {} diff --git a/test_crates/trait_must_use_added/old/Cargo.toml b/test_crates/trait_must_use_added/old/Cargo.toml new file mode 100644 index 00000000..5965321c --- /dev/null +++ b/test_crates/trait_must_use_added/old/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "trait_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/trait_must_use_added/old/src/lib.rs b/test_crates/trait_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..32e95381 --- /dev/null +++ b/test_crates/trait_must_use_added/old/src/lib.rs @@ -0,0 +1,30 @@ +// These traits did not have the #[must_use] attribute in the old version. +// Addition of the attribute should be reported by this rule. + +pub trait TraitToMustUseTrait {} + +pub trait TraitToMustUseMessageTrait {} + + +// These traits 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 trait MustUseTraitToTrait {} + +#[must_use] +pub trait MustUseTraitToMustUseMessageTrait {} + + +// These traits 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 trait MustUseMessageTraitToTrait {} + +#[must_use = "Foo"] +pub trait MustUseMessageTraitToMustUseTrait {} + +#[must_use = "Foo"] +pub trait MustUseMessageTraitToMustUseMessageTrait {} diff --git a/test_outputs/trait_must_use_added.output.ron b/test_outputs/trait_must_use_added.output.ron new file mode 100644 index 00000000..8c0807e5 --- /dev/null +++ b/test_outputs/trait_must_use_added.output.ron @@ -0,0 +1,26 @@ +{ + "./test_crates/trait_must_use_added/": [ + { + "name": String("TraitToMustUseTrait"), + "new_attr": String("#[must_use]"), + "path": List([ + String("trait_must_use_added"), + String("TraitToMustUseTrait"), + ]), + "span_begin_line": Uint64(5), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "name": String("TraitToMustUseMessageTrait"), + "new_attr": String("#[must_use = \"Foo\"]"), + "path": List([ + String("trait_must_use_added"), + String("TraitToMustUseMessageTrait"), + ]), + "span_begin_line": Uint64(8), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], +} From 33e7992e84f7ff468417dcd892be48f4f1458c51 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Sun, 8 Jan 2023 19:58:00 +0100 Subject: [PATCH 08/18] Additional tests with private items. --- test_crates/enum_must_use_added/new/src/lib.rs | 8 ++++++++ test_crates/enum_must_use_added/old/src/lib.rs | 7 +++++++ test_crates/function_must_use_added/new/src/lib.rs | 8 ++++++++ test_crates/function_must_use_added/old/src/lib.rs | 7 +++++++ test_crates/struct_must_use_added/new/src/lib.rs | 8 ++++++++ test_crates/struct_must_use_added/old/src/lib.rs | 7 +++++++ 6 files changed, 45 insertions(+) diff --git a/test_crates/enum_must_use_added/new/src/lib.rs b/test_crates/enum_must_use_added/new/src/lib.rs index acf9c967..4920bf51 100644 --- a/test_crates/enum_must_use_added/new/src/lib.rs +++ b/test_crates/enum_must_use_added/new/src/lib.rs @@ -42,3 +42,11 @@ pub enum MustUseMessageEnumToMustUseEnum { pub enum MustUseMessageEnumToMustUseMessageEnum { Bar, } + + +// This enum is private and should not be reported by this rule. + +#[must_use] +enum MustUsePrivateEnum { + Bar, +} diff --git a/test_crates/enum_must_use_added/old/src/lib.rs b/test_crates/enum_must_use_added/old/src/lib.rs index 805fa043..32b67b87 100644 --- a/test_crates/enum_must_use_added/old/src/lib.rs +++ b/test_crates/enum_must_use_added/old/src/lib.rs @@ -42,3 +42,10 @@ pub enum MustUseMessageEnumToMustUseEnum { pub enum MustUseMessageEnumToMustUseMessageEnum { Bar, } + + +// This enum is private and should not be reported by this rule. + +enum MustUsePrivateEnum { + Bar, +} diff --git a/test_crates/function_must_use_added/new/src/lib.rs b/test_crates/function_must_use_added/new/src/lib.rs index da993f13..394b909d 100644 --- a/test_crates/function_must_use_added/new/src/lib.rs +++ b/test_crates/function_must_use_added/new/src/lib.rs @@ -42,3 +42,11 @@ pub fn MustUseMessageFunctionToMustUseFunction(x: i64) -> i64 { pub fn MustUseMessageFunctionToMustUseMessageFunction(x: i64) -> i64 { x } + + +// This function is private and should not be reported by this rule. + +#[must_use] +fn MustUsePrivateFunction(x: i64) -> i64 { + x +} diff --git a/test_crates/function_must_use_added/old/src/lib.rs b/test_crates/function_must_use_added/old/src/lib.rs index 528eeb24..5f202d2c 100644 --- a/test_crates/function_must_use_added/old/src/lib.rs +++ b/test_crates/function_must_use_added/old/src/lib.rs @@ -42,3 +42,10 @@ pub fn MustUseMessageFunctionToMustUseFunction(x: i64) -> i64 { pub fn MustUseMessageFunctionToMustUseMessageFunction(x: i64) -> i64 { x } + + +// This function is private and should not be reported by this rule. + +fn MustUsePrivateFunction(x: i64) -> i64 { + x +} diff --git a/test_crates/struct_must_use_added/new/src/lib.rs b/test_crates/struct_must_use_added/new/src/lib.rs index 72787321..9115ed87 100644 --- a/test_crates/struct_must_use_added/new/src/lib.rs +++ b/test_crates/struct_must_use_added/new/src/lib.rs @@ -42,3 +42,11 @@ pub struct MustUseMessageStructToMustUseStruct { pub struct MustUseMessageStructToMustUseMessageStruct { bar: u64, } + + +// This struct is private and should not be reported by this rule. + +#[must_use] +struct MustUsePrivateStruct { + bar: u64, +} diff --git a/test_crates/struct_must_use_added/old/src/lib.rs b/test_crates/struct_must_use_added/old/src/lib.rs index 4621b2c2..67ae0af7 100644 --- a/test_crates/struct_must_use_added/old/src/lib.rs +++ b/test_crates/struct_must_use_added/old/src/lib.rs @@ -42,3 +42,10 @@ pub struct MustUseMessageStructToMustUseStruct { pub struct MustUseMessageStructToMustUseMessageStruct { bar: u64, } + + +// This struct is private and should not be reported by this rule. + +struct MustUsePrivateStruct { + bar: u64, +} From 659430e88e34eee192e9efc5c3c9f06b3d5d3330 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 11:13:59 +0100 Subject: [PATCH 09/18] Missing test - private trait must_use added --- test_crates/trait_must_use_added/new/src/lib.rs | 6 ++++++ test_crates/trait_must_use_added/old/src/lib.rs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/test_crates/trait_must_use_added/new/src/lib.rs b/test_crates/trait_must_use_added/new/src/lib.rs index 9bfa4a9c..74207d81 100644 --- a/test_crates/trait_must_use_added/new/src/lib.rs +++ b/test_crates/trait_must_use_added/new/src/lib.rs @@ -28,3 +28,9 @@ pub trait MustUseMessageTraitToMustUseTrait {} #[must_use = "Baz"] pub trait MustUseMessageTraitToMustUseMessageTrait {} + + +// This trait is private and should not be reported by this rule. + +#[must_use] +trait MustUsePrivateTrait {} diff --git a/test_crates/trait_must_use_added/old/src/lib.rs b/test_crates/trait_must_use_added/old/src/lib.rs index 32e95381..6d38235a 100644 --- a/test_crates/trait_must_use_added/old/src/lib.rs +++ b/test_crates/trait_must_use_added/old/src/lib.rs @@ -28,3 +28,8 @@ pub trait MustUseMessageTraitToMustUseTrait {} #[must_use = "Foo"] pub trait MustUseMessageTraitToMustUseMessageTrait {} + + +// This trait is private and should not be reported by this rule. + +trait MustUsePrivateTrait {} From 96a134bbfd9d5d088d846703b07170323561f6e5 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 18:50:37 +0100 Subject: [PATCH 10/18] Simpler functions in function_must_use_added. --- .../function_must_use_added/new/src/lib.rs | 32 +++++-------------- .../function_must_use_added/old/src/lib.rs | 32 +++++-------------- 2 files changed, 16 insertions(+), 48 deletions(-) diff --git a/test_crates/function_must_use_added/new/src/lib.rs b/test_crates/function_must_use_added/new/src/lib.rs index 394b909d..bc77e0f1 100644 --- a/test_crates/function_must_use_added/new/src/lib.rs +++ b/test_crates/function_must_use_added/new/src/lib.rs @@ -2,51 +2,35 @@ // Addition of the attribute should be reported by this rule. #[must_use] -pub fn FunctionToMustUseFunction(x: i64) -> i64 { - x -} +pub fn FunctionToMustUseFunction() {} #[must_use = "Foo"] -pub fn FunctionToMustUseMessageFunction(x: i64) -> i64 { - x -} +pub fn FunctionToMustUseMessageFunction() {} // These functions had the #[must_use] attribute in the old version. Changes of // the attribute, including deletion, should not be reported by this rule. -pub fn MustUseFunctionToFunction(x: i64) -> i64 { - x -} +pub fn MustUseFunctionToFunction() {} #[must_use = "Foo"] -pub fn MustUseFunctionToMustUseMessageFunction(x: i64) -> i64 { - x -} +pub fn MustUseFunctionToMustUseMessageFunction() {} // These functions 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 fn MustUseMessageFunctionToFunction(x: i64) -> i64 { - x -} +pub fn MustUseMessageFunctionToFunction() {} #[must_use] -pub fn MustUseMessageFunctionToMustUseFunction(x: i64) -> i64 { - x -} +pub fn MustUseMessageFunctionToMustUseFunction() {} #[must_use = "Baz"] -pub fn MustUseMessageFunctionToMustUseMessageFunction(x: i64) -> i64 { - x -} +pub fn MustUseMessageFunctionToMustUseMessageFunction() {} // This function is private and should not be reported by this rule. #[must_use] -fn MustUsePrivateFunction(x: i64) -> i64 { - x -} +fn MustUsePrivateFunction() {} diff --git a/test_crates/function_must_use_added/old/src/lib.rs b/test_crates/function_must_use_added/old/src/lib.rs index 5f202d2c..9c55b2d2 100644 --- a/test_crates/function_must_use_added/old/src/lib.rs +++ b/test_crates/function_must_use_added/old/src/lib.rs @@ -1,27 +1,19 @@ // These functions did not have the #[must_use] attribute in the old version. // Addition of the attribute should be reported by this rule. -pub fn FunctionToMustUseFunction(x: i64) -> i64 { - x -} +pub fn FunctionToMustUseFunction() {} -pub fn FunctionToMustUseMessageFunction(x: i64) -> i64 { - x -} +pub fn FunctionToMustUseMessageFunction() {} // These functions 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 fn MustUseFunctionToFunction(x: i64) -> i64 { - x -} +pub fn MustUseFunctionToFunction() {} #[must_use] -pub fn MustUseFunctionToMustUseMessageFunction(x: i64) -> i64 { - x -} +pub fn MustUseFunctionToMustUseMessageFunction() {} // These functions had the #[must_use] attribute in the old version. @@ -29,23 +21,15 @@ pub fn MustUseFunctionToMustUseMessageFunction(x: i64) -> i64 { // the attribute, including deletion, should not be reported by this rule. #[must_use = "Foo"] -pub fn MustUseMessageFunctionToFunction(x: i64) -> i64 { - x -} +pub fn MustUseMessageFunctionToFunction() {} #[must_use = "Foo"] -pub fn MustUseMessageFunctionToMustUseFunction(x: i64) -> i64 { - x -} +pub fn MustUseMessageFunctionToMustUseFunction() {} #[must_use = "Foo"] -pub fn MustUseMessageFunctionToMustUseMessageFunction(x: i64) -> i64 { - x -} +pub fn MustUseMessageFunctionToMustUseMessageFunction() {} // This function is private and should not be reported by this rule. -fn MustUsePrivateFunction(x: i64) -> i64 { - x -} +fn MustUsePrivateFunction() {} From ee7c1e1462e8ef9ba327312af773cc5a8b459fc5 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 19:14:54 +0100 Subject: [PATCH 11/18] Correct the line numbers in function_must_use_added.output.ron file. --- test_outputs/function_must_use_added.output.ron | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_outputs/function_must_use_added.output.ron b/test_outputs/function_must_use_added.output.ron index 96fe2a07..dc871d7e 100644 --- a/test_outputs/function_must_use_added.output.ron +++ b/test_outputs/function_must_use_added.output.ron @@ -18,7 +18,7 @@ String("function_must_use_added"), String("FunctionToMustUseMessageFunction"), ]), - "span_begin_line": Uint64(10), + "span_begin_line": Uint64(8), "span_filename": String("src/lib.rs"), "visibility_limit": String("public"), }, From ba2c051a38270962276d6707bbfbd840c59f76b7 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 19:16:12 +0100 Subject: [PATCH 12/18] Additional test - adding new item with initial must_use. --- test_crates/enum_must_use_added/new/src/lib.rs | 10 ++++++++++ test_crates/function_must_use_added/new/src/lib.rs | 8 ++++++++ test_crates/struct_must_use_added/new/src/lib.rs | 10 ++++++++++ test_crates/trait_must_use_added/new/src/lib.rs | 8 ++++++++ 4 files changed, 36 insertions(+) diff --git a/test_crates/enum_must_use_added/new/src/lib.rs b/test_crates/enum_must_use_added/new/src/lib.rs index 4920bf51..a243733a 100644 --- a/test_crates/enum_must_use_added/new/src/lib.rs +++ b/test_crates/enum_must_use_added/new/src/lib.rs @@ -50,3 +50,13 @@ pub enum MustUseMessageEnumToMustUseMessageEnum { enum MustUsePrivateEnum { Bar, } + + +// This enum was added in the new version of the crate with it's attribute. +// It should not be reported by this rule because adding a new enum is not +// a breaking change. + +#[must_use] +pub enum MustUseNewEnum { + Bar, +} diff --git a/test_crates/function_must_use_added/new/src/lib.rs b/test_crates/function_must_use_added/new/src/lib.rs index bc77e0f1..0a889905 100644 --- a/test_crates/function_must_use_added/new/src/lib.rs +++ b/test_crates/function_must_use_added/new/src/lib.rs @@ -34,3 +34,11 @@ pub fn MustUseMessageFunctionToMustUseMessageFunction() {} #[must_use] fn MustUsePrivateFunction() {} + + +// This function was added in the new version of the crate with it's attribute. +// It should not be reported by this rule because adding a new function is not +// a breaking change. + +#[must_use] +pub fn MustUseNewFunction() {} diff --git a/test_crates/struct_must_use_added/new/src/lib.rs b/test_crates/struct_must_use_added/new/src/lib.rs index 9115ed87..a3782197 100644 --- a/test_crates/struct_must_use_added/new/src/lib.rs +++ b/test_crates/struct_must_use_added/new/src/lib.rs @@ -50,3 +50,13 @@ pub struct MustUseMessageStructToMustUseMessageStruct { struct MustUsePrivateStruct { bar: u64, } + + +// This struct was added in the new version of the crate with it's attribute. +// It should not be reported by this rule because adding a new struct is not +// a breaking change. + +#[must_use] +pub struct MustUseNewStruct { + bar: u64, +} diff --git a/test_crates/trait_must_use_added/new/src/lib.rs b/test_crates/trait_must_use_added/new/src/lib.rs index 74207d81..ac74ae97 100644 --- a/test_crates/trait_must_use_added/new/src/lib.rs +++ b/test_crates/trait_must_use_added/new/src/lib.rs @@ -34,3 +34,11 @@ pub trait MustUseMessageTraitToMustUseMessageTrait {} #[must_use] trait MustUsePrivateTrait {} + + +// This trait was added in the new version of the crate with it's attribute. +// It should not be reported by this rule because adding a new trait is not +// a breaking change. + +#[must_use] +pub trait MustUseNewTrait {} From 68264c95b45116860b9fef1a7d1362a0751b4177 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 20:12:54 +0100 Subject: [PATCH 13/18] Backup commit before file splitting. --- src/lints/method_must_use_added.ron | 89 +++++ .../method_must_use_added/new/Cargo.toml | 6 + .../method_must_use_added/new/src/lib.rs | 325 ++++++++++++++++++ .../method_must_use_added/old/Cargo.toml | 6 + .../method_must_use_added/old/src/lib.rs | 239 +++++++++++++ test_outputs/method_must_use_added.output.ron | 5 + 6 files changed, 670 insertions(+) create mode 100644 src/lints/method_must_use_added.ron create mode 100644 test_crates/method_must_use_added/new/Cargo.toml create mode 100644 test_crates/method_must_use_added/new/src/lib.rs create mode 100644 test_crates/method_must_use_added/old/Cargo.toml create mode 100644 test_crates/method_must_use_added/old/src/lib.rs create mode 100644 test_outputs/method_must_use_added.output.ron diff --git a/src/lints/method_must_use_added.ron b/src/lints/method_must_use_added.ron new file mode 100644 index 00000000..82624113 --- /dev/null +++ b/src/lints/method_must_use_added.ron @@ -0,0 +1,89 @@ +SemverQuery( + id: "method_must_use_added", + human_readable_name: "method #[must_use] added", + description: "A 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 { + baseline { + item { + ... on ImplOwner { + visibility_limit @filter(op: "=", value: ["$public"]) @output + name @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 @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { + content { + base @filter(op: "=", value: ["$must_use"]) + } + } + } + } + } + } + } + current { + item { + ... on ImplOwner { + visibility_limit @filter(op: "=", value: ["$public"]) + name @filter(op: "=", value: ["%name"]) + + importable_path { + path @filter(op: "=", value: ["%path"]) + } + + # We use "impl" instead of "inherent_impl" here because moving + # an inherently-implemented method to a trait is not necessarily + # a breaking change, so we don't want to report it. + # + # It is also important to notice that #[must_use] can only be + # added to the method declaration or definition inside the trait. + # When #[must_use] is added to the definition inside an + # impl for <...> the attribute is ignored as only + # the attributes from the trait method declaration are applied. + + impl { + method { + visibility_limit @filter(op: "one_of", value: ["$public_or_default"]) + name @filter(op: "=", value: ["%method_name"]) + + attribute { + new_attr: raw_attribute @output + content { + base @filter(op: "=", value: ["$must_use"]) + } + } + + span_: span @optional { + filename @output + begin_line @output + } + } + } + } + } + } + } + }"#, + arguments: { + "public": "public", + "public_or_default": ["public", "default"], + "must_use": "must_use", + "zero": 0, + }, + error_message: "A method has been marked with #[must_use]. This can cause downstream crates that did not use the value returned by this method to get a compiler lint.", + per_result_error_template: Some("method {{join \"::\" path}}::{{method_name}} in {{span_filename}}:{{span_begin_line}}"), +) diff --git a/test_crates/method_must_use_added/new/Cargo.toml b/test_crates/method_must_use_added/new/Cargo.toml new file mode 100644 index 00000000..ca610517 --- /dev/null +++ b/test_crates/method_must_use_added/new/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "method_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/method_must_use_added/new/src/lib.rs b/test_crates/method_must_use_added/new/src/lib.rs new file mode 100644 index 00000000..b0500e85 --- /dev/null +++ b/test_crates/method_must_use_added/new/src/lib.rs @@ -0,0 +1,325 @@ +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) {} +} + + +pub struct StructWithMovedProvidedMustUseMethods {} + +pub trait TraitWithMovedProvidedMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + #[must_use] + fn MethodToMovedProvidedMustUseMethod(&self) {} + + #[must_use = "Foo"] + fn MethodToMovedProvidedMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + fn MustUseMethodToMovedProvidedMethod(&self) {} + + #[must_use = "Foo"] + fn MustUseMethodToMovedProvidedMustUseMessageMethod(&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. + + fn MustUseMessageMethodToMovedProvidedMethod(&self) {} + + #[must_use] + fn MustUseMessageMethodToMovedProvidedMustUseMethod(&self) {} + + #[must_use = "Baz"] + fn MustUseMessageMethodToMovedProvidedMustUseMessageMethod(&self) {} +} + +impl TraitWithMovedProvidedMustUseMethods for StructWithMovedProvidedMustUseMethods {} + + +pub struct StructWithMovedDeclaredMustUseMethods {} + +pub trait TraitWithMovedDeclaredMustUseMethods { + + #[must_use] + fn MethodToMovedDeclaredMustUseMethod(&self); + + #[must_use = "Foo"] + fn MethodToMovedDeclaredMustUseMessageMethod(&self); + + fn MustUseMethodToMovedDeclaredMethod(&self); + + #[must_use = "Foo"] + fn MustUseMethodToMovedDeclaredMustUseMessageMethod(&self); + + fn MustUseMessageMethodToMovedDeclaredMethod(&self); + + #[must_use] + fn MustUseMessageMethodToMovedDeclaredMustUseMethod(&self); + + #[must_use = "Baz"] + fn MustUseMessageMethodToMovedDeclaredMustUseMessageMethod(&self); +} + +impl TraitWithMovedDeclaredMustUseMethods for StructWithMovedDeclaredMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + fn MethodToMovedDeclaredMustUseMethod(&self) {} + + fn MethodToMovedDeclaredMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + fn MustUseMethodToMovedDeclaredMethod(&self) {} + + fn MustUseMethodToMovedDeclaredMustUseMessageMethod(&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. + + fn MustUseMessageMethodToMovedDeclaredMethod(&self) {} + + fn MustUseMessageMethodToMovedDeclaredMustUseMethod(&self) {} + + fn MustUseMessageMethodToMovedDeclaredMustUseMessageMethod(&self) {} +} + + +pub trait TraitWithDeclaredMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + #[must_use] + fn DeclaredMethodToDeclaredMustUseMethod(&self); + + #[must_use = "Foo"] + fn DeclaredMethodToDeclaredMustUseMessageMethod(&self); + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + fn DeclaredMustUseMethodToDeclaredMethod(&self); + + #[must_use = "Foo"] + fn DeclaredMustUseMethodToDeclaredMustUseMessageMethod(&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. + + fn DeclaredMustUseMessageMethodToDeclaredMethod(&self); + + #[must_use] + fn DeclaredMustUseMessageMethodToDeclaredMustUseMethod(&self); + + #[must_use = "Baz"] + fn DeclaredMustUseMessageMethodToDeclaredMustUseMessageMethod(&self); +} + + +pub trait TraitWithProvidedMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + #[must_use] + fn ProvidedMethodToProvidedMustUseMethod(&self) {} + + #[must_use = "Foo"] + fn ProvidedMethodToProvidedMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + fn ProvidedMustUseMethodToProvidedMethod(&self) {} + + #[must_use = "Foo"] + fn ProvidedMustUseMethodToProvidedMustUseMessageMethod(&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. + + fn ProvidedMustUseMessageMethodToProvidedMethod(&self) {} + + #[must_use] + fn ProvidedMustUseMessageMethodToProvidedMustUseMethod(&self) {} + + #[must_use = "Baz"] + fn ProvidedMustUseMessageMethodToProvidedMustUseMessageMethod(&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 it's methods, +// after moving them to a private trait, should NOT be reported. + +struct PrivateStructWithMovedMustUseMethods {} + +trait PrivateTraitWithMovedMustUseMethods { + + #[must_use] + fn PrivateStructMethodToMovedPrivateDeclaredMustUseMethod(&self); + + #[must_use] + fn PrivateStructMethodToMovedPrivateProvidedMustUseMethod(&self) {} + + #[must_use] + fn PrivateStructMethodToMovedPrivateOverrideMustUseMethod(&self) {} +} + +impl PrivateTraitWithMovedMustUseMethods for PrivateStructWithMovedMustUseMethods { + + fn PrivateStructMethodToMovedPrivateDeclaredMustUseMethod(&self) {} + + fn PrivateStructMethodToMovedPrivateOverrideMustUseMethod(&self) {} +} + + +// This trait is private and adding #[must_use] to it's methods +// should NOT be reported. + +trait PrivateTraitWithMustUseMethods { + + #[must_use] + fn PrivateDeclaredMethodToPrivateDeclaredMustUseMethod(&self); + + #[must_use] + fn PrivateProvidedMethodToPrivateProvidedMustUseMethod(&self) {} +} + + +// Adding the #[must_use] attribute inside a trait's impl block +// does NOT generate a compiler lint when calling inner methods +// without using their return value. Thus it should NOT be reported. + +pub struct StructWithMovedImplMustUseMethods {} + +pub trait TraitWithMovedImplMustUseMethods { + + fn MethodToMovedImplDeclaredMustUseMethod(&self); + + fn MethodToMovedImplOverrideMustUseMethod(&self) {} +} + +impl TraitWithMovedImplMustUseMethods for StructWithMovedImplMustUseMethods { + + #[must_use] + fn MethodToMovedImplDeclaredMustUseMethod(&self) {} + + #[must_use] + fn MethodToMovedImplOverrideMustUseMethod(&self) {} +} + + +// This struct and it's inherent method were added in the new version of the +// crate, together with the method's attribute. It should NOT be reported +// because adding a new struct is not a breaking change. + +pub struct NewStructWithMustUseMethods {} + +impl NewStructWithMustUseMethods { + + #[must_use] + pub fn NewStructMustUseMethod(&self) {} +} + + +// This struct, trait and it's inherent methods were added in the new version of +// the crate, together with the method's attribute. It should NOT be reported +// because adding a new struct or trait is not a breaking change. + +pub struct NewStructWithTraitMustUseMethods {} + +pub trait NewTraitWithStructMustUseMethods { + + #[must_use] + fn NewTraitWithStructDeclaredMustUseMethod(&self); + + #[must_use] + fn NewTraitWithStructProvidedMustUseMethod(&self) {} + + #[must_use] + fn NewTraitWithStructOverrideMustUseMethod(&self) {} +} + +impl NewTraitWithStructMustUseMethods for NewStructWithTraitMustUseMethods { + + fn NewTraitWithStructDeclaredMustUseMethod(&self) {} + + fn NewTraitWithStructOverrideMustUseMethod(&self) {} +} + + +// This trait and it's methods were added in the new version of the crate, +// together with the method's attribute. It should NOT be reported because +// adding a new trait is not a breaking change. + +pub trait NewTraitWithMustUseMethods { + + #[must_use] + fn NewTraitWithDeclaredMustUseMethod(&self); + + #[must_use] + fn NewTraitWithProvidedMustUseMethod(&self) {} +} diff --git a/test_crates/method_must_use_added/old/Cargo.toml b/test_crates/method_must_use_added/old/Cargo.toml new file mode 100644 index 00000000..ca610517 --- /dev/null +++ b/test_crates/method_must_use_added/old/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "method_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/method_must_use_added/old/src/lib.rs b/test_crates/method_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..668894d7 --- /dev/null +++ b/test_crates/method_must_use_added/old/src/lib.rs @@ -0,0 +1,239 @@ +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) {} +} + + +pub struct StructWithMovedProvidedMustUseMethods {} + +impl StructWithMovedProvidedMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + pub fn MethodToMovedProvidedMustUseMethod(&self) {} + + pub fn MethodToMovedProvidedMustUseMessageMethod(&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 MustUseMethodToMovedProvidedMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMovedProvidedMustUseMessageMethod(&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 MustUseMessageMethodToMovedProvidedMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMovedProvidedMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMovedProvidedMustUseMessageMethod(&self) {} +} + +pub trait TraitWithMovedProvidedMustUseMethods {} + + +pub struct StructWithMovedDeclaredMustUseMethods {} + +impl StructWithMovedDeclaredMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + pub fn MethodToMovedDeclaredMustUseMethod(&self) {} + + pub fn MethodToMovedDeclaredMustUseMessageMethod(&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 MustUseMethodToMovedDeclaredMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMovedDeclaredMustUseMessageMethod(&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 MustUseMessageMethodToMovedDeclaredMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMovedDeclaredMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMovedDeclaredMustUseMessageMethod(&self) {} +} + +pub trait TraitWithMovedDeclaredMustUseMethods {} + + +pub trait TraitWithDeclaredMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + fn DeclaredMethodToDeclaredMustUseMethod(&self); + + fn DeclaredMethodToDeclaredMustUseMessageMethod(&self); + + + // These methods had the #[must_use] attribute in the old version. Changes + // of the attribute, including deletion, should not be reported. + + #[must_use] + fn DeclaredMustUseMethodToDeclaredMethod(&self); + + #[must_use] + fn DeclaredMustUseMethodToDeclaredMustUseMessageMethod(&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"] + fn DeclaredMustUseMessageMethodToDeclaredMethod(&self); + + #[must_use = "Foo"] + fn DeclaredMustUseMessageMethodToDeclaredMustUseMethod(&self); + + #[must_use = "Foo"] + fn DeclaredMustUseMessageMethodToDeclaredMustUseMessageMethod(&self); +} + + +pub trait TraitWithProvidedMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + fn ProvidedMethodToProvidedMustUseMethod(&self) {} + + fn ProvidedMethodToProvidedMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes + // of the attribute, including deletion, should not be reported. + + #[must_use] + fn ProvidedMustUseMethodToProvidedMethod(&self) {} + + #[must_use] + fn ProvidedMustUseMethodToProvidedMustUseMessageMethod(&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"] + fn ProvidedMustUseMessageMethodToProvidedMethod(&self) {} + + #[must_use = "Foo"] + fn ProvidedMustUseMessageMethodToProvidedMustUseMethod(&self) {} + + #[must_use = "Foo"] + fn ProvidedMustUseMessageMethodToProvidedMustUseMessageMethod(&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 it's methods, +// after moving them to a private trait, should NOT be reported. + +struct PrivateStructWithMovedMustUseMethods {} + +impl PrivateStructWithMovedMustUseMethods { + + pub fn PrivateStructMethodToMovedPrivateDeclaredMustUseMethod(&self) {} + + pub fn PrivateStructMethodToMovedPrivateProvidedMustUseMethod(&self) {} + + pub fn PrivateStructMethodToMovedPrivateOverrideMustUseMethod(&self) {} +} + +trait PrivateTraitWithMovedMustUseMethods {} + + +// This trait is private and adding #[must_use] to it's methods +// should NOT be reported. + +trait PrivateTraitWithMustUseMethods { + + fn PrivateDeclaredMethodToPrivateDeclaredMustUseMethod(&self); + + fn PrivateProvidedMethodToPrivateProvidedMustUseMethod(&self) {} +} + + +// Adding the #[must_use] attribute inside a trait's impl block +// does NOT generate a compiler lint when calling inner methods +// without using the return value. Thus it should NOT be reported. + +pub struct StructWithMovedImplMustUseMethods {} + +impl StructWithMovedImplMustUseMethods { + + pub fn MethodToMovedImplDeclaredMustUseMethod(&self) {} + + pub fn MethodToMovedImplOverrideMustUseMethod(&self) {} +} + +pub trait TraitWithMovedImplMustUseMethods {} diff --git a/test_outputs/method_must_use_added.output.ron b/test_outputs/method_must_use_added.output.ron new file mode 100644 index 00000000..7f42b1cc --- /dev/null +++ b/test_outputs/method_must_use_added.output.ron @@ -0,0 +1,5 @@ +{ + "./test_crates/method_must_use_added/": [ + // TODO + ] +} From ffebed4b40a140b4f3073e305216d6bdbd27a577 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 20:30:50 +0100 Subject: [PATCH 14/18] New lint: inherent_method_must_use_added --- src/lints/inherent_method_must_use_added.ron | 78 +++++++++++++++++++ src/query.rs | 1 + .../new/Cargo.toml | 6 ++ .../new/src/lib.rs | 73 +++++++++++++++++ .../old/Cargo.toml | 6 ++ .../old/src/lib.rs | 58 ++++++++++++++ .../inherent_method_must_use_added.output.ron | 30 +++++++ 7 files changed, 252 insertions(+) create mode 100644 src/lints/inherent_method_must_use_added.ron create mode 100644 test_crates/inherent_method_must_use_added/new/Cargo.toml create mode 100644 test_crates/inherent_method_must_use_added/new/src/lib.rs create mode 100644 test_crates/inherent_method_must_use_added/old/Cargo.toml create mode 100644 test_crates/inherent_method_must_use_added/old/src/lib.rs create mode 100644 test_outputs/inherent_method_must_use_added.output.ron 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..e62212f9 --- /dev/null +++ b/src/lints/inherent_method_must_use_added.ron @@ -0,0 +1,78 @@ +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 { + baseline { + item { + ... on ImplOwner { + visibility_limit @filter(op: "=", value: ["$public"]) @output + name @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 @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { + content { + base @filter(op: "=", value: ["$must_use"]) + } + } + } + } + } + } + } + current { + item { + ... on ImplOwner { + visibility_limit @filter(op: "=", value: ["$public"]) + name @filter(op: "=", value: ["%name"]) + + importable_path { + path @filter(op: "=", value: ["%path"]) + } + + inherent_impl { + method { + visibility_limit @filter(op: "=", value: ["$public"]) + name @filter(op: "=", value: ["%method_name"]) + + 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 inherent_method has been marked with #[must_use]. This can cause downstream crates that did not use the value returned by this method to get a compiler lint.", + per_result_error_template: Some("inherent_method {{join \"::\" path}}::{{method_name}} in {{span_filename}}:{{span_begin_line}}"), +) diff --git a/src/query.rs b/src/query.rs index 1f5d9917..6b935e19 100644 --- a/src/query.rs +++ b/src/query.rs @@ -440,4 +440,5 @@ add_lints!( struct_must_use_added, function_must_use_added, trait_must_use_added, + inherent_method_must_use_added, ); 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..6c98db59 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/new/Cargo.toml @@ -0,0 +1,6 @@ +[package] +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/lib.rs b/test_crates/inherent_method_must_use_added/new/src/lib.rs new file mode 100644 index 00000000..834708c8 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/new/src/lib.rs @@ -0,0 +1,73 @@ +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 it's inherent methods +// should NOT be reported. + +struct PrivateStructWithMustUseMethods {} + +impl PrivateStructWithMustUseMethods { + + #[must_use] + fn PrivateStructMethodToPrivateStructMustUseMethod(&self) {} +} + + +// This struct and it's inherent method were added in the new version of the +// crate, together with the method's attribute. It should NOT be reported +// because adding a new struct is not a breaking change. + +pub struct NewStructWithMustUseMethods {} + +impl NewStructWithMustUseMethods { + + #[must_use] + pub fn NewStructMustUseMethod(&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..6c98db59 --- /dev/null +++ b/test_crates/inherent_method_must_use_added/old/Cargo.toml @@ -0,0 +1,6 @@ +[package] +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/lib.rs b/test_crates/inherent_method_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..62525e4e --- /dev/null +++ b/test_crates/inherent_method_must_use_added/old/src/lib.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 it's inherent methods +// should NOT be reported. + +struct PrivateStructWithMustUseMethods {} + +impl PrivateStructWithMustUseMethods { + + fn PrivateStructMethodToPrivateStructMustUseMethod(&self) {} +} 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..86931109 --- /dev/null +++ b/test_outputs/inherent_method_must_use_added.output.ron @@ -0,0 +1,30 @@ +{ + "./test_crates/inherent_method_must_use_added/": [ + { + "method_name": String("MethodToMustUseMethod"), + "method_visibility": String("public"), + "name": String("StructWithMustUseMethods"), + "new_attr": String("#[must_use]"), + "path": List([ + String("inherent_method_must_use_added"), + String("StructWithMustUseMethods"), + ]), + "span_begin_line": Uint64(9), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + { + "method_name": String("MethodToMustUseMessageMethod"), + "method_visibility": String("public"), + "name": String("StructWithMustUseMethods"), + "new_attr": String("#[must_use = \"Foo\"]"), + "path": List([ + String("inherent_method_must_use_added"), + String("StructWithMustUseMethods"), + ]), + "span_begin_line": Uint64(12), + "span_filename": String("src/lib.rs"), + "visibility_limit": String("public"), + }, + ], +} From 62acdda12db89650b241b6fce463141a4b027aa8 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 20:35:24 +0100 Subject: [PATCH 15/18] More comment emphasis in tests against false-positives :) --- test_crates/enum_must_use_added/new/src/lib.rs | 8 ++++---- test_crates/enum_must_use_added/old/src/lib.rs | 6 +++--- test_crates/function_must_use_added/new/src/lib.rs | 8 ++++---- test_crates/function_must_use_added/old/src/lib.rs | 6 +++--- test_crates/struct_must_use_added/new/src/lib.rs | 8 ++++---- test_crates/struct_must_use_added/old/src/lib.rs | 6 +++--- test_crates/trait_must_use_added/new/src/lib.rs | 8 ++++---- test_crates/trait_must_use_added/old/src/lib.rs | 6 +++--- 8 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test_crates/enum_must_use_added/new/src/lib.rs b/test_crates/enum_must_use_added/new/src/lib.rs index a243733a..48b99b76 100644 --- a/test_crates/enum_must_use_added/new/src/lib.rs +++ b/test_crates/enum_must_use_added/new/src/lib.rs @@ -13,7 +13,7 @@ pub enum EnumToMustUseMessageEnum { // These enums had the #[must_use] attribute in the old version. Changes of -// the attribute, including deletion, should not be reported by this rule. +// the attribute, including deletion, should NOT be reported by this rule. pub enum MustUseEnumToEnum { Bar, @@ -27,7 +27,7 @@ pub enum MustUseEnumToMustUseMessageEnum { // 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. +// the attribute, including deletion, should NOT be reported by this rule. pub enum MustUseMessageEnumToEnum { Bar, @@ -44,7 +44,7 @@ pub enum MustUseMessageEnumToMustUseMessageEnum { } -// This enum is private and should not be reported by this rule. +// This enum is private and should NOT be reported by this rule. #[must_use] enum MustUsePrivateEnum { @@ -53,7 +53,7 @@ enum MustUsePrivateEnum { // This enum was added in the new version of the crate with it's attribute. -// It should not be reported by this rule because adding a new enum is not +// It should NOT be reported by this rule because adding a new enum is not // a breaking change. #[must_use] diff --git a/test_crates/enum_must_use_added/old/src/lib.rs b/test_crates/enum_must_use_added/old/src/lib.rs index 32b67b87..c27a2965 100644 --- a/test_crates/enum_must_use_added/old/src/lib.rs +++ b/test_crates/enum_must_use_added/old/src/lib.rs @@ -11,7 +11,7 @@ pub enum EnumToMustUseMessageEnum { // These enums had the #[must_use] attribute in the old version. Changes of -// the attribute, including deletion, should not be reported by this rule. +// the attribute, including deletion, should NOT be reported by this rule. #[must_use] pub enum MustUseEnumToEnum { @@ -26,7 +26,7 @@ pub enum MustUseEnumToMustUseMessageEnum { // 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. +// the attribute, including deletion, should NOT be reported by this rule. #[must_use = "Foo"] pub enum MustUseMessageEnumToEnum { @@ -44,7 +44,7 @@ pub enum MustUseMessageEnumToMustUseMessageEnum { } -// This enum is private and should not be reported by this rule. +// This enum is private and should NOT be reported by this rule. enum MustUsePrivateEnum { Bar, diff --git a/test_crates/function_must_use_added/new/src/lib.rs b/test_crates/function_must_use_added/new/src/lib.rs index 0a889905..87c0ccd7 100644 --- a/test_crates/function_must_use_added/new/src/lib.rs +++ b/test_crates/function_must_use_added/new/src/lib.rs @@ -9,7 +9,7 @@ pub fn FunctionToMustUseMessageFunction() {} // These functions had the #[must_use] attribute in the old version. Changes of -// the attribute, including deletion, should not be reported by this rule. +// the attribute, including deletion, should NOT be reported by this rule. pub fn MustUseFunctionToFunction() {} @@ -19,7 +19,7 @@ pub fn MustUseFunctionToMustUseMessageFunction() {} // These functions 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. +// the attribute, including deletion, should NOT be reported by this rule. pub fn MustUseMessageFunctionToFunction() {} @@ -30,14 +30,14 @@ pub fn MustUseMessageFunctionToMustUseFunction() {} pub fn MustUseMessageFunctionToMustUseMessageFunction() {} -// This function is private and should not be reported by this rule. +// This function is private and should NOT be reported by this rule. #[must_use] fn MustUsePrivateFunction() {} // This function was added in the new version of the crate with it's attribute. -// It should not be reported by this rule because adding a new function is not +// It should NOT be reported by this rule because adding a new function is not // a breaking change. #[must_use] diff --git a/test_crates/function_must_use_added/old/src/lib.rs b/test_crates/function_must_use_added/old/src/lib.rs index 9c55b2d2..dc6172f3 100644 --- a/test_crates/function_must_use_added/old/src/lib.rs +++ b/test_crates/function_must_use_added/old/src/lib.rs @@ -7,7 +7,7 @@ pub fn FunctionToMustUseMessageFunction() {} // These functions had the #[must_use] attribute in the old version. Changes of -// the attribute, including deletion, should not be reported by this rule. +// the attribute, including deletion, should NOT be reported by this rule. #[must_use] pub fn MustUseFunctionToFunction() {} @@ -18,7 +18,7 @@ pub fn MustUseFunctionToMustUseMessageFunction() {} // These functions 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. +// the attribute, including deletion, should NOT be reported by this rule. #[must_use = "Foo"] pub fn MustUseMessageFunctionToFunction() {} @@ -30,6 +30,6 @@ pub fn MustUseMessageFunctionToMustUseFunction() {} pub fn MustUseMessageFunctionToMustUseMessageFunction() {} -// This function is private and should not be reported by this rule. +// This function is private and should NOT be reported by this rule. fn MustUsePrivateFunction() {} diff --git a/test_crates/struct_must_use_added/new/src/lib.rs b/test_crates/struct_must_use_added/new/src/lib.rs index a3782197..4dff93f2 100644 --- a/test_crates/struct_must_use_added/new/src/lib.rs +++ b/test_crates/struct_must_use_added/new/src/lib.rs @@ -13,7 +13,7 @@ pub struct StructToMustUseMessageStruct { // These structs had the #[must_use] attribute in the old version. Changes of -// the attribute, including deletion, should not be reported by this rule. +// the attribute, including deletion, should NOT be reported by this rule. pub struct MustUseStructToStruct { bar: u64, @@ -27,7 +27,7 @@ pub struct MustUseStructToMustUseMessageStruct { // These structs 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. +// the attribute, including deletion, should NOT be reported by this rule. pub struct MustUseMessageStructToStruct { bar: u64, @@ -44,7 +44,7 @@ pub struct MustUseMessageStructToMustUseMessageStruct { } -// This struct is private and should not be reported by this rule. +// This struct is private and should NOT be reported by this rule. #[must_use] struct MustUsePrivateStruct { @@ -53,7 +53,7 @@ struct MustUsePrivateStruct { // This struct was added in the new version of the crate with it's attribute. -// It should not be reported by this rule because adding a new struct is not +// It should NOT be reported by this rule because adding a new struct is not // a breaking change. #[must_use] diff --git a/test_crates/struct_must_use_added/old/src/lib.rs b/test_crates/struct_must_use_added/old/src/lib.rs index 67ae0af7..1a749ab0 100644 --- a/test_crates/struct_must_use_added/old/src/lib.rs +++ b/test_crates/struct_must_use_added/old/src/lib.rs @@ -11,7 +11,7 @@ pub struct StructToMustUseMessageStruct { // These structs had the #[must_use] attribute in the old version. Changes of -// the attribute, including deletion, should not be reported by this rule. +// the attribute, including deletion, should NOT be reported by this rule. #[must_use] pub struct MustUseStructToStruct { @@ -26,7 +26,7 @@ pub struct MustUseStructToMustUseMessageStruct { // These structs 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. +// the attribute, including deletion, should NOT be reported by this rule. #[must_use = "Foo"] pub struct MustUseMessageStructToStruct { @@ -44,7 +44,7 @@ pub struct MustUseMessageStructToMustUseMessageStruct { } -// This struct is private and should not be reported by this rule. +// This struct is private and should NOT be reported by this rule. struct MustUsePrivateStruct { bar: u64, diff --git a/test_crates/trait_must_use_added/new/src/lib.rs b/test_crates/trait_must_use_added/new/src/lib.rs index ac74ae97..c102410c 100644 --- a/test_crates/trait_must_use_added/new/src/lib.rs +++ b/test_crates/trait_must_use_added/new/src/lib.rs @@ -9,7 +9,7 @@ pub trait TraitToMustUseMessageTrait {} // These traits had the #[must_use] attribute in the old version. Changes of -// the attribute, including deletion, should not be reported by this rule. +// the attribute, including deletion, should NOT be reported by this rule. pub trait MustUseTraitToTrait {} @@ -19,7 +19,7 @@ pub trait MustUseTraitToMustUseMessageTrait {} // These traits 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. +// the attribute, including deletion, should NOT be reported by this rule. pub trait MustUseMessageTraitToTrait {} @@ -30,14 +30,14 @@ pub trait MustUseMessageTraitToMustUseTrait {} pub trait MustUseMessageTraitToMustUseMessageTrait {} -// This trait is private and should not be reported by this rule. +// This trait is private and should NOT be reported by this rule. #[must_use] trait MustUsePrivateTrait {} // This trait was added in the new version of the crate with it's attribute. -// It should not be reported by this rule because adding a new trait is not +// It should NOT be reported by this rule because adding a new trait is not // a breaking change. #[must_use] diff --git a/test_crates/trait_must_use_added/old/src/lib.rs b/test_crates/trait_must_use_added/old/src/lib.rs index 6d38235a..d4660165 100644 --- a/test_crates/trait_must_use_added/old/src/lib.rs +++ b/test_crates/trait_must_use_added/old/src/lib.rs @@ -7,7 +7,7 @@ pub trait TraitToMustUseMessageTrait {} // These traits had the #[must_use] attribute in the old version. Changes of -// the attribute, including deletion, should not be reported by this rule. +// the attribute, including deletion, should NOT be reported by this rule. #[must_use] pub trait MustUseTraitToTrait {} @@ -18,7 +18,7 @@ pub trait MustUseTraitToMustUseMessageTrait {} // These traits 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. +// the attribute, including deletion, should NOT be reported by this rule. #[must_use = "Foo"] pub trait MustUseMessageTraitToTrait {} @@ -30,6 +30,6 @@ pub trait MustUseMessageTraitToMustUseTrait {} pub trait MustUseMessageTraitToMustUseMessageTrait {} -// This trait is private and should not be reported by this rule. +// This trait is private and should NOT be reported by this rule. trait MustUsePrivateTrait {} From a96d6a449ab8085cb3009400a00240a734c3d6c1 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 20:41:42 +0100 Subject: [PATCH 16/18] Removed unnecessary underscores '_'. --- src/lints/inherent_method_must_use_added.ron | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lints/inherent_method_must_use_added.ron b/src/lints/inherent_method_must_use_added.ron index e62212f9..e7590038 100644 --- a/src/lints/inherent_method_must_use_added.ron +++ b/src/lints/inherent_method_must_use_added.ron @@ -1,7 +1,7 @@ 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].", + 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 @@ -73,6 +73,6 @@ SemverQuery( "must_use": "must_use", "zero": 0, }, - error_message: "An inherent_method has been marked with #[must_use]. This can cause downstream crates that did not use the value returned by this method to get a compiler lint.", - per_result_error_template: Some("inherent_method {{join \"::\" path}}::{{method_name}} in {{span_filename}}:{{span_begin_line}}"), + error_message: "An inherent method has been marked with #[must_use]. This can cause downstream crates that did not use the value returned by this method to get a compiler lint.", + per_result_error_template: Some("inherent method {{join \"::\" path}}::{{method_name}} in {{span_filename}}:{{span_begin_line}}"), ) From b138f79107ebd6790cfb7f9f3956b89d7a2cd61a Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 22:56:19 +0100 Subject: [PATCH 17/18] New test crate: trait_method_must_use_added --- .../new/Cargo.toml | 6 ++ .../new/src/lib.rs | 95 +++++++++++++++++++ .../old/Cargo.toml | 6 ++ .../old/src/lib.rs | 79 +++++++++++++++ 4 files changed, 186 insertions(+) create mode 100644 test_crates/trait_method_must_use_added/new/Cargo.toml create mode 100644 test_crates/trait_method_must_use_added/new/src/lib.rs create mode 100644 test_crates/trait_method_must_use_added/old/Cargo.toml create mode 100644 test_crates/trait_method_must_use_added/old/src/lib.rs diff --git a/test_crates/trait_method_must_use_added/new/Cargo.toml b/test_crates/trait_method_must_use_added/new/Cargo.toml new file mode 100644 index 00000000..34afe366 --- /dev/null +++ b/test_crates/trait_method_must_use_added/new/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "trait_method_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/trait_method_must_use_added/new/src/lib.rs b/test_crates/trait_method_must_use_added/new/src/lib.rs new file mode 100644 index 00000000..738c5da1 --- /dev/null +++ b/test_crates/trait_method_must_use_added/new/src/lib.rs @@ -0,0 +1,95 @@ +pub trait TraitWithDeclaredMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + #[must_use] + fn DeclaredMethodToDeclaredMustUseMethod(&self); + + #[must_use = "Foo"] + fn DeclaredMethodToDeclaredMustUseMessageMethod(&self); + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + fn DeclaredMustUseMethodToDeclaredMethod(&self); + + #[must_use = "Foo"] + fn DeclaredMustUseMethodToDeclaredMustUseMessageMethod(&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. + + fn DeclaredMustUseMessageMethodToDeclaredMethod(&self); + + #[must_use] + fn DeclaredMustUseMessageMethodToDeclaredMustUseMethod(&self); + + #[must_use = "Baz"] + fn DeclaredMustUseMessageMethodToDeclaredMustUseMessageMethod(&self); +} + + +pub trait TraitWithProvidedMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + #[must_use] + fn ProvidedMethodToProvidedMustUseMethod(&self) {} + + #[must_use = "Foo"] + fn ProvidedMethodToProvidedMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes of + // the attribute, including deletion, should not be reported. + + fn ProvidedMustUseMethodToProvidedMethod(&self) {} + + #[must_use = "Foo"] + fn ProvidedMustUseMethodToProvidedMustUseMessageMethod(&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. + + fn ProvidedMustUseMessageMethodToProvidedMethod(&self) {} + + #[must_use] + fn ProvidedMustUseMessageMethodToProvidedMustUseMethod(&self) {} + + #[must_use = "Baz"] + fn ProvidedMustUseMessageMethodToProvidedMustUseMessageMethod(&self) {} +} + + +// This trait is private and adding #[must_use] to it's methods +// should NOT be reported. + +trait PrivateTraitWithMustUseMethods { + + #[must_use] + fn PrivateDeclaredMethodToPrivateDeclaredMustUseMethod(&self); + + #[must_use] + fn PrivateProvidedMethodToPrivateProvidedMustUseMethod(&self) {} +} + + +// This trait and it's methods were added in the new version of the crate, +// together with the method's attribute. It should NOT be reported because +// adding a new trait is not a breaking change. + +pub trait NewTraitWithMustUseMethods { + + #[must_use] + fn NewTraitWithDeclaredMustUseMethod(&self); + + #[must_use] + fn NewTraitWithProvidedMustUseMethod(&self) {} +} diff --git a/test_crates/trait_method_must_use_added/old/Cargo.toml b/test_crates/trait_method_must_use_added/old/Cargo.toml new file mode 100644 index 00000000..34afe366 --- /dev/null +++ b/test_crates/trait_method_must_use_added/old/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "trait_method_must_use_added" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test_crates/trait_method_must_use_added/old/src/lib.rs b/test_crates/trait_method_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..5a60d5dd --- /dev/null +++ b/test_crates/trait_method_must_use_added/old/src/lib.rs @@ -0,0 +1,79 @@ +pub trait TraitWithDeclaredMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + fn DeclaredMethodToDeclaredMustUseMethod(&self); + + fn DeclaredMethodToDeclaredMustUseMessageMethod(&self); + + + // These methods had the #[must_use] attribute in the old version. Changes + // of the attribute, including deletion, should not be reported. + + #[must_use] + fn DeclaredMustUseMethodToDeclaredMethod(&self); + + #[must_use] + fn DeclaredMustUseMethodToDeclaredMustUseMessageMethod(&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"] + fn DeclaredMustUseMessageMethodToDeclaredMethod(&self); + + #[must_use = "Foo"] + fn DeclaredMustUseMessageMethodToDeclaredMustUseMethod(&self); + + #[must_use = "Foo"] + fn DeclaredMustUseMessageMethodToDeclaredMustUseMessageMethod(&self); +} + + +pub trait TraitWithProvidedMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + fn ProvidedMethodToProvidedMustUseMethod(&self) {} + + fn ProvidedMethodToProvidedMustUseMessageMethod(&self) {} + + + // These methods had the #[must_use] attribute in the old version. Changes + // of the attribute, including deletion, should not be reported. + + #[must_use] + fn ProvidedMustUseMethodToProvidedMethod(&self) {} + + #[must_use] + fn ProvidedMustUseMethodToProvidedMustUseMessageMethod(&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"] + fn ProvidedMustUseMessageMethodToProvidedMethod(&self) {} + + #[must_use = "Foo"] + fn ProvidedMustUseMessageMethodToProvidedMustUseMethod(&self) {} + + #[must_use = "Foo"] + fn ProvidedMustUseMessageMethodToProvidedMustUseMessageMethod(&self) {} +} + + +// This trait is private and adding #[must_use] to it's methods +// should NOT be reported. + +trait PrivateTraitWithMustUseMethods { + + fn PrivateDeclaredMethodToPrivateDeclaredMustUseMethod(&self); + + fn PrivateProvidedMethodToPrivateProvidedMustUseMethod(&self) {} +} From f950f99e02f7de6c7bd1b5aafda4f6197e9c6122 Mon Sep 17 00:00:00 2001 From: Bartosz Smolarczyk Date: Mon, 9 Jan 2023 23:17:51 +0100 Subject: [PATCH 18/18] New test crate: inherent_method_moved_must_use_added --- .../new/Cargo.toml | 2 +- .../new/src/lib.rs | 160 ------------ .../old/Cargo.toml | 2 +- .../old/src/lib.rs | 108 ++++++++ .../method_must_use_added/old/src/lib.rs | 239 ------------------ 5 files changed, 110 insertions(+), 401 deletions(-) rename test_crates/{method_must_use_added => inherent_method_moved_must_use_added}/new/Cargo.toml (57%) rename test_crates/{method_must_use_added => inherent_method_moved_must_use_added}/new/src/lib.rs (51%) rename test_crates/{method_must_use_added => inherent_method_moved_must_use_added}/old/Cargo.toml (57%) create mode 100644 test_crates/inherent_method_moved_must_use_added/old/src/lib.rs delete mode 100644 test_crates/method_must_use_added/old/src/lib.rs diff --git a/test_crates/method_must_use_added/new/Cargo.toml b/test_crates/inherent_method_moved_must_use_added/new/Cargo.toml similarity index 57% rename from test_crates/method_must_use_added/new/Cargo.toml rename to test_crates/inherent_method_moved_must_use_added/new/Cargo.toml index ca610517..4d6f75de 100644 --- a/test_crates/method_must_use_added/new/Cargo.toml +++ b/test_crates/inherent_method_moved_must_use_added/new/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "method_must_use_added" +name = "inherent_method_moved_must_use_added" version = "0.1.0" edition = "2021" diff --git a/test_crates/method_must_use_added/new/src/lib.rs b/test_crates/inherent_method_moved_must_use_added/new/src/lib.rs similarity index 51% rename from test_crates/method_must_use_added/new/src/lib.rs rename to test_crates/inherent_method_moved_must_use_added/new/src/lib.rs index b0500e85..8ccc4c32 100644 --- a/test_crates/method_must_use_added/new/src/lib.rs +++ b/test_crates/inherent_method_moved_must_use_added/new/src/lib.rs @@ -1,40 +1,3 @@ -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) {} -} - - pub struct StructWithMovedProvidedMustUseMethods {} pub trait TraitWithMovedProvidedMustUseMethods { @@ -128,89 +91,6 @@ impl TraitWithMovedDeclaredMustUseMethods for StructWithMovedDeclaredMustUseMeth } -pub trait TraitWithDeclaredMustUseMethods { - - // These methods did not have the #[must_use] attribute in the old version. - // Addition of the attribute should be reported. - - #[must_use] - fn DeclaredMethodToDeclaredMustUseMethod(&self); - - #[must_use = "Foo"] - fn DeclaredMethodToDeclaredMustUseMessageMethod(&self); - - - // These methods had the #[must_use] attribute in the old version. Changes of - // the attribute, including deletion, should not be reported. - - fn DeclaredMustUseMethodToDeclaredMethod(&self); - - #[must_use = "Foo"] - fn DeclaredMustUseMethodToDeclaredMustUseMessageMethod(&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. - - fn DeclaredMustUseMessageMethodToDeclaredMethod(&self); - - #[must_use] - fn DeclaredMustUseMessageMethodToDeclaredMustUseMethod(&self); - - #[must_use = "Baz"] - fn DeclaredMustUseMessageMethodToDeclaredMustUseMessageMethod(&self); -} - - -pub trait TraitWithProvidedMustUseMethods { - - // These methods did not have the #[must_use] attribute in the old version. - // Addition of the attribute should be reported. - - #[must_use] - fn ProvidedMethodToProvidedMustUseMethod(&self) {} - - #[must_use = "Foo"] - fn ProvidedMethodToProvidedMustUseMessageMethod(&self) {} - - - // These methods had the #[must_use] attribute in the old version. Changes of - // the attribute, including deletion, should not be reported. - - fn ProvidedMustUseMethodToProvidedMethod(&self) {} - - #[must_use = "Foo"] - fn ProvidedMustUseMethodToProvidedMustUseMessageMethod(&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. - - fn ProvidedMustUseMessageMethodToProvidedMethod(&self) {} - - #[must_use] - fn ProvidedMustUseMessageMethodToProvidedMustUseMethod(&self) {} - - #[must_use = "Baz"] - fn ProvidedMustUseMessageMethodToProvidedMustUseMessageMethod(&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 it's methods, // after moving them to a private trait, should NOT be reported. @@ -236,19 +116,6 @@ impl PrivateTraitWithMovedMustUseMethods for PrivateStructWithMovedMustUseMethod } -// This trait is private and adding #[must_use] to it's methods -// should NOT be reported. - -trait PrivateTraitWithMustUseMethods { - - #[must_use] - fn PrivateDeclaredMethodToPrivateDeclaredMustUseMethod(&self); - - #[must_use] - fn PrivateProvidedMethodToPrivateProvidedMustUseMethod(&self) {} -} - - // Adding the #[must_use] attribute inside a trait's impl block // does NOT generate a compiler lint when calling inner methods // without using their return value. Thus it should NOT be reported. @@ -272,19 +139,6 @@ impl TraitWithMovedImplMustUseMethods for StructWithMovedImplMustUseMethods { } -// This struct and it's inherent method were added in the new version of the -// crate, together with the method's attribute. It should NOT be reported -// because adding a new struct is not a breaking change. - -pub struct NewStructWithMustUseMethods {} - -impl NewStructWithMustUseMethods { - - #[must_use] - pub fn NewStructMustUseMethod(&self) {} -} - - // This struct, trait and it's inherent methods were added in the new version of // the crate, together with the method's attribute. It should NOT be reported // because adding a new struct or trait is not a breaking change. @@ -309,17 +163,3 @@ impl NewTraitWithStructMustUseMethods for NewStructWithTraitMustUseMethods { fn NewTraitWithStructOverrideMustUseMethod(&self) {} } - - -// This trait and it's methods were added in the new version of the crate, -// together with the method's attribute. It should NOT be reported because -// adding a new trait is not a breaking change. - -pub trait NewTraitWithMustUseMethods { - - #[must_use] - fn NewTraitWithDeclaredMustUseMethod(&self); - - #[must_use] - fn NewTraitWithProvidedMustUseMethod(&self) {} -} diff --git a/test_crates/method_must_use_added/old/Cargo.toml b/test_crates/inherent_method_moved_must_use_added/old/Cargo.toml similarity index 57% rename from test_crates/method_must_use_added/old/Cargo.toml rename to test_crates/inherent_method_moved_must_use_added/old/Cargo.toml index ca610517..4d6f75de 100644 --- a/test_crates/method_must_use_added/old/Cargo.toml +++ b/test_crates/inherent_method_moved_must_use_added/old/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "method_must_use_added" +name = "inherent_method_moved_must_use_added" version = "0.1.0" edition = "2021" diff --git a/test_crates/inherent_method_moved_must_use_added/old/src/lib.rs b/test_crates/inherent_method_moved_must_use_added/old/src/lib.rs new file mode 100644 index 00000000..397e0043 --- /dev/null +++ b/test_crates/inherent_method_moved_must_use_added/old/src/lib.rs @@ -0,0 +1,108 @@ +pub struct StructWithMovedProvidedMustUseMethods {} + +impl StructWithMovedProvidedMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + pub fn MethodToMovedProvidedMustUseMethod(&self) {} + + pub fn MethodToMovedProvidedMustUseMessageMethod(&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 MustUseMethodToMovedProvidedMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMovedProvidedMustUseMessageMethod(&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 MustUseMessageMethodToMovedProvidedMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMovedProvidedMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMovedProvidedMustUseMessageMethod(&self) {} +} + +pub trait TraitWithMovedProvidedMustUseMethods {} + + +pub struct StructWithMovedDeclaredMustUseMethods {} + +impl StructWithMovedDeclaredMustUseMethods { + + // These methods did not have the #[must_use] attribute in the old version. + // Addition of the attribute should be reported. + + pub fn MethodToMovedDeclaredMustUseMethod(&self) {} + + pub fn MethodToMovedDeclaredMustUseMessageMethod(&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 MustUseMethodToMovedDeclaredMethod(&self) {} + + #[must_use] + pub fn MustUseMethodToMovedDeclaredMustUseMessageMethod(&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 MustUseMessageMethodToMovedDeclaredMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMovedDeclaredMustUseMethod(&self) {} + + #[must_use = "Foo"] + pub fn MustUseMessageMethodToMovedDeclaredMustUseMessageMethod(&self) {} +} + +pub trait TraitWithMovedDeclaredMustUseMethods {} + +// This struct is private and adding #[must_use] to it's methods, +// after moving them to a private trait, should NOT be reported. + +struct PrivateStructWithMovedMustUseMethods {} + +impl PrivateStructWithMovedMustUseMethods { + + pub fn PrivateStructMethodToMovedPrivateDeclaredMustUseMethod(&self) {} + + pub fn PrivateStructMethodToMovedPrivateProvidedMustUseMethod(&self) {} + + pub fn PrivateStructMethodToMovedPrivateOverrideMustUseMethod(&self) {} +} + +trait PrivateTraitWithMovedMustUseMethods {} + + +// Adding the #[must_use] attribute inside a trait's impl block +// does NOT generate a compiler lint when calling inner methods +// without using the return value. Thus it should NOT be reported. + +pub struct StructWithMovedImplMustUseMethods {} + +impl StructWithMovedImplMustUseMethods { + + pub fn MethodToMovedImplDeclaredMustUseMethod(&self) {} + + pub fn MethodToMovedImplOverrideMustUseMethod(&self) {} +} + +pub trait TraitWithMovedImplMustUseMethods {} diff --git a/test_crates/method_must_use_added/old/src/lib.rs b/test_crates/method_must_use_added/old/src/lib.rs deleted file mode 100644 index 668894d7..00000000 --- a/test_crates/method_must_use_added/old/src/lib.rs +++ /dev/null @@ -1,239 +0,0 @@ -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) {} -} - - -pub struct StructWithMovedProvidedMustUseMethods {} - -impl StructWithMovedProvidedMustUseMethods { - - // These methods did not have the #[must_use] attribute in the old version. - // Addition of the attribute should be reported. - - pub fn MethodToMovedProvidedMustUseMethod(&self) {} - - pub fn MethodToMovedProvidedMustUseMessageMethod(&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 MustUseMethodToMovedProvidedMethod(&self) {} - - #[must_use] - pub fn MustUseMethodToMovedProvidedMustUseMessageMethod(&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 MustUseMessageMethodToMovedProvidedMethod(&self) {} - - #[must_use = "Foo"] - pub fn MustUseMessageMethodToMovedProvidedMustUseMethod(&self) {} - - #[must_use = "Foo"] - pub fn MustUseMessageMethodToMovedProvidedMustUseMessageMethod(&self) {} -} - -pub trait TraitWithMovedProvidedMustUseMethods {} - - -pub struct StructWithMovedDeclaredMustUseMethods {} - -impl StructWithMovedDeclaredMustUseMethods { - - // These methods did not have the #[must_use] attribute in the old version. - // Addition of the attribute should be reported. - - pub fn MethodToMovedDeclaredMustUseMethod(&self) {} - - pub fn MethodToMovedDeclaredMustUseMessageMethod(&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 MustUseMethodToMovedDeclaredMethod(&self) {} - - #[must_use] - pub fn MustUseMethodToMovedDeclaredMustUseMessageMethod(&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 MustUseMessageMethodToMovedDeclaredMethod(&self) {} - - #[must_use = "Foo"] - pub fn MustUseMessageMethodToMovedDeclaredMustUseMethod(&self) {} - - #[must_use = "Foo"] - pub fn MustUseMessageMethodToMovedDeclaredMustUseMessageMethod(&self) {} -} - -pub trait TraitWithMovedDeclaredMustUseMethods {} - - -pub trait TraitWithDeclaredMustUseMethods { - - // These methods did not have the #[must_use] attribute in the old version. - // Addition of the attribute should be reported. - - fn DeclaredMethodToDeclaredMustUseMethod(&self); - - fn DeclaredMethodToDeclaredMustUseMessageMethod(&self); - - - // These methods had the #[must_use] attribute in the old version. Changes - // of the attribute, including deletion, should not be reported. - - #[must_use] - fn DeclaredMustUseMethodToDeclaredMethod(&self); - - #[must_use] - fn DeclaredMustUseMethodToDeclaredMustUseMessageMethod(&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"] - fn DeclaredMustUseMessageMethodToDeclaredMethod(&self); - - #[must_use = "Foo"] - fn DeclaredMustUseMessageMethodToDeclaredMustUseMethod(&self); - - #[must_use = "Foo"] - fn DeclaredMustUseMessageMethodToDeclaredMustUseMessageMethod(&self); -} - - -pub trait TraitWithProvidedMustUseMethods { - - // These methods did not have the #[must_use] attribute in the old version. - // Addition of the attribute should be reported. - - fn ProvidedMethodToProvidedMustUseMethod(&self) {} - - fn ProvidedMethodToProvidedMustUseMessageMethod(&self) {} - - - // These methods had the #[must_use] attribute in the old version. Changes - // of the attribute, including deletion, should not be reported. - - #[must_use] - fn ProvidedMustUseMethodToProvidedMethod(&self) {} - - #[must_use] - fn ProvidedMustUseMethodToProvidedMustUseMessageMethod(&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"] - fn ProvidedMustUseMessageMethodToProvidedMethod(&self) {} - - #[must_use = "Foo"] - fn ProvidedMustUseMessageMethodToProvidedMustUseMethod(&self) {} - - #[must_use = "Foo"] - fn ProvidedMustUseMessageMethodToProvidedMustUseMessageMethod(&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 it's methods, -// after moving them to a private trait, should NOT be reported. - -struct PrivateStructWithMovedMustUseMethods {} - -impl PrivateStructWithMovedMustUseMethods { - - pub fn PrivateStructMethodToMovedPrivateDeclaredMustUseMethod(&self) {} - - pub fn PrivateStructMethodToMovedPrivateProvidedMustUseMethod(&self) {} - - pub fn PrivateStructMethodToMovedPrivateOverrideMustUseMethod(&self) {} -} - -trait PrivateTraitWithMovedMustUseMethods {} - - -// This trait is private and adding #[must_use] to it's methods -// should NOT be reported. - -trait PrivateTraitWithMustUseMethods { - - fn PrivateDeclaredMethodToPrivateDeclaredMustUseMethod(&self); - - fn PrivateProvidedMethodToPrivateProvidedMustUseMethod(&self) {} -} - - -// Adding the #[must_use] attribute inside a trait's impl block -// does NOT generate a compiler lint when calling inner methods -// without using the return value. Thus it should NOT be reported. - -pub struct StructWithMovedImplMustUseMethods {} - -impl StructWithMovedImplMustUseMethods { - - pub fn MethodToMovedImplDeclaredMustUseMethod(&self) {} - - pub fn MethodToMovedImplOverrideMustUseMethod(&self) {} -} - -pub trait TraitWithMovedImplMustUseMethods {}