Skip to content

Commit

Permalink
New lint - detecting field removals from a struct variant in enum (ob…
Browse files Browse the repository at this point in the history
…i1kenobi#156)

* Added first, untested code

* Changed tabs to spaces

* First nonworking test

* Fixed test

* Changed occurences of structvariant with struct_variant

* Improved descriptions

Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com>
  • Loading branch information
tonowak and obi1kenobi authored Oct 20, 2022
1 parent 3d585a1 commit 19fa6aa
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions semver_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum_repr_int_removed = []
enum_repr_c_removed = []
enum_variant_added = []
enum_variant_missing = []
enum_struct_variant_field_missing = []
function_missing = []
inherent_method_missing = []
sized_impl_removed = []
Expand Down
19 changes: 19 additions & 0 deletions semver_tests/src/test_cases/enum_struct_variant_field_missing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pub enum Enum {
FieldWillBeMissing {
foo: usize,

/// Testing: <https://doc.rust-lang.org/cargo/reference/semver.html#item-remove>
#[cfg(not(feature = "enum_struct_variant_field_missing"))]
bar: usize,
}
}

/// This struct variant should not be reported by the `enum_struct_variant_field_missing` rule:
/// it will be removed altogether, so the correct rule to catch it is
/// the `enum_variant_missing` rule and not the rule for missing fields.
pub enum IgnoredEnum {
#[cfg(not(feature = "enum_struct_variant_field_missing"))]
StructVariantWillBeMissing {
foo: usize,
}
}
1 change: 1 addition & 0 deletions semver_tests/src/test_cases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod enum_repr_int_changed;
pub mod enum_repr_int_removed;
pub mod enum_variant_added;
pub mod enum_variant_missing;
pub mod enum_struct_variant_field_missing;
pub mod item_missing;
pub mod non_exhaustive;
pub mod sized_impl_removed;
Expand Down
66 changes: 66 additions & 0 deletions src/queries/enum_struct_variant_field_missing.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
SemverQuery(
id: "enum_struct_variant_field_missing",
human_readable_name: "pub enum struct variant's field removed or renamed" ,
description: "An enum's struct variant has a field that is no longer available under its prior name.",
required_update: Major,
reference_link: Some("https://doc.rust-lang.org/cargo/reference/semver.html#item-remove"),
query: r#"
{
CrateDiff {
baseline {
item {
... on Enum {
visibility_limit @filter(op: "=", value: ["$public"])
enum_name: name @output @tag
importable_path {
path @output @tag
}
variant {
... on StructVariant {
variant_name: name @output @tag
field {
field_name: name @output @tag
span_: span @optional {
filename @output
begin_line @output
}
}
}
}
}
}
}
current {
item {
... on Enum {
visibility_limit @filter(op: "=", value: ["$public"])
name @filter(op: "=", value: ["%enum_name"])
importable_path {
path @filter(op: "=", value: ["%path"])
}
variant {
... on StructVariant {
name @filter(op: "=", value: ["%variant_name"])
field @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) {
name @filter(op: "=", value: ["%field_name"])
}
}
}
}
}
}
}
}"#,
arguments: {
"public": "public",
"zero": 0,
},
error_message: "A publicly-visible enum has a struct variant whose field is no longer available under its prior name. It may have been renamed or removed entirely.",
per_result_error_template: Some("field {{field_name}} of variant {{enum_name}}::{{variant_name}}, previously in file {{span_filename}}:{{span_begin_line}}"),
)
2 changes: 2 additions & 0 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl SemverQuery {
include_str!("./queries/enum_repr_int_removed.ron"),
include_str!("./queries/enum_variant_added.ron"),
include_str!("./queries/enum_variant_missing.ron"),
include_str!("./queries/enum_struct_variant_field_missing.ron"),
include_str!("./queries/function_missing.ron"),
include_str!("./queries/inherent_method_missing.ron"),
include_str!("./queries/sized_impl_removed.ron"),
Expand Down Expand Up @@ -280,6 +281,7 @@ mod tests {
enum_repr_int_removed,
enum_variant_added,
enum_variant_missing,
enum_struct_variant_field_missing,
function_missing,
inherent_method_missing,
sized_impl_removed,
Expand Down
15 changes: 15 additions & 0 deletions src/test_data/enum_struct_variant_field_missing.output.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"enum_name": String("Enum"),
"variant_name": String("FieldWillBeMissing"),
"path": List([
String("semver_tests"),
String("test_cases"),
String("enum_struct_variant_field_missing"),
String("Enum"),
]),
"field_name": String("bar"),
"span_filename": String("src/test_cases/enum_struct_variant_field_missing.rs"),
"span_begin_line": Uint64(7),
}
]

0 comments on commit 19fa6aa

Please sign in to comment.