Skip to content

Commit aeccda8

Browse files
authoredMar 24, 2025
Chore: Add witness hint for enum_variant_added lint (#1218)
Adds a witness hint for the `enum_variant_added` lint. ## Example `enum_variant_added` outputs the following witness hint for the `./test_crates/enum_variant_added/` test. ```rust match value { enum_variant_added::EnumWithNewVariant::OldVariant => (), enum_variant_added::EnumWithNewVariant::OldStructVariant { .. } => (), enum_variant_added::EnumWithNewVariant::OldTupleVariant(..) => (), } ``` This compiles on the old version, but not on the new due to the lack of exhaustiveness on the match cases. The lack of a catch-all case causes the addition of a new variant to cause a compilation error. ## Commit Notes + Added witness hint for enum_variant_added + Added new parts to query for enum_variant_added to fetch relevant data for the witness + Update test crates to allow for more exhaustive witness format testing ## Comments Two questions and possible areas for bigger improvements: 1. Is there a better way to combine `baseline_variant_names` and `baseline_variant_kinds`? They both form lists, but each list is separate from the other. Now, each should still always form the same length of list as the other, as they are tied to the same `variant` query, but if there is a way to combine/tuple them together, that would be good to know so I can make that adjustment. 2. Is it okay to modify tests like I've done here? It doesn't change the final result of the test, it all runs the same, I just added some new variants to the tested enum so that I can test the witness printing unit-like, struct-like, and tuple-like enum variants.
1 parent 6e932d0 commit aeccda8

File tree

5 files changed

+81
-2
lines changed

5 files changed

+81
-2
lines changed
 

‎src/lints/enum_variant_added.ron

+11
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ SemverQuery(
4646
variant @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) {
4747
name @filter(op: "=", value: ["%variant_name"])
4848
}
49+
50+
variant @fold {
51+
baseline_variant_kinds: __typename @output
52+
53+
baseline_variant_names: name @output
54+
}
4955
}
5056
}
5157
}
@@ -59,4 +65,9 @@ SemverQuery(
5965
},
6066
error_message: "A publicly-visible enum without #[non_exhaustive] has a new variant.",
6167
per_result_error_template: Some("variant {{enum_name}}:{{variant_name}} in {{span_filename}}:{{span_begin_line}}"),
68+
witness: (
69+
hint_template: r#"match value { {{#each baseline_variant_kinds }}
70+
{{ join "::" ../path }}::{{lookup ../baseline_variant_names @index}}{{#if (eq this "StructVariant")}} { .. }{{/if}}{{#if (eq this "TupleVariant")}}(..){{/if}} => (),{{/each}}
71+
}"#,
72+
),
6273
)

‎test_crates/enum_variant_added/new/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
pub enum EnumWithNewVariant {
44
OldVariant,
5+
6+
OldStructVariant {
7+
x: i64,
8+
},
9+
10+
OldTupleVariant(i64),
511

612
NewVariant,
713
}

‎test_crates/enum_variant_added/old/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
pub enum EnumWithNewVariant {
44
OldVariant,
5+
6+
OldStructVariant {
7+
x: i64,
8+
},
9+
10+
OldTupleVariant(i64)
511
}
612

713
/// This enum should not be reported by the `enum_variant_added` rule,

‎test_outputs/query_execution/enum_variant_added.snap

+26-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ snapshot_kind: text
66
{
77
"./test_crates/enum_discriminant_no_longer_defined/": [
88
{
9+
"baseline_variant_kinds": List([
10+
String("PlainVariant"),
11+
]),
12+
"baseline_variant_names": List([
13+
String("None"),
14+
]),
915
"enum_name": String("GainsStructVariant"),
1016
"path": List([
1117
String("enum_discriminant_no_longer_defined"),
@@ -20,20 +26,38 @@ snapshot_kind: text
2026
],
2127
"./test_crates/enum_variant_added/": [
2228
{
29+
"baseline_variant_kinds": List([
30+
String("PlainVariant"),
31+
String("StructVariant"),
32+
String("TupleVariant"),
33+
]),
34+
"baseline_variant_names": List([
35+
String("OldVariant"),
36+
String("OldStructVariant"),
37+
String("OldTupleVariant"),
38+
]),
2339
"enum_name": String("EnumWithNewVariant"),
2440
"path": List([
2541
String("enum_variant_added"),
2642
String("EnumWithNewVariant"),
2743
]),
28-
"span_begin_line": Uint64(6),
29-
"span_end_line": Uint64(6),
44+
"span_begin_line": Uint64(12),
45+
"span_end_line": Uint64(12),
3046
"span_filename": String("src/lib.rs"),
3147
"variant_name": String("NewVariant"),
3248
"visibility_limit": String("public"),
3349
},
3450
],
3551
"./test_crates/enum_variant_hidden_from_public_api/": [
3652
{
53+
"baseline_variant_kinds": List([
54+
String("PlainVariant"),
55+
String("PlainVariant"),
56+
]),
57+
"baseline_variant_names": List([
58+
String("First"),
59+
String("Second"),
60+
]),
3761
"enum_name": String("AddedVariant"),
3862
"path": List([
3963
String("enum_variant_hidden_from_public_api"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
source: src/query.rs
3+
description: "Lint `enum_variant_added` did not have the expected witness output.\nSee https://github.com/obi1kenobi/cargo-semver-checks/blob/main/CONTRIBUTING.md#testing-witnesses\nfor more information."
4+
expression: "&actual_witnesses"
5+
snapshot_kind: text
6+
---
7+
[["./test_crates/enum_discriminant_no_longer_defined/"]]
8+
filename = 'src/lib.rs'
9+
begin_line = 69
10+
hint = '''
11+
match value {
12+
enum_discriminant_no_longer_defined::GainsStructVariant::None => (),
13+
}'''
14+
15+
[["./test_crates/enum_variant_added/"]]
16+
filename = 'src/lib.rs'
17+
begin_line = 12
18+
hint = '''
19+
match value {
20+
enum_variant_added::EnumWithNewVariant::OldVariant => (),
21+
enum_variant_added::EnumWithNewVariant::OldStructVariant { .. } => (),
22+
enum_variant_added::EnumWithNewVariant::OldTupleVariant(..) => (),
23+
}'''
24+
25+
[["./test_crates/enum_variant_hidden_from_public_api/"]]
26+
filename = 'src/lib.rs'
27+
begin_line = 18
28+
hint = '''
29+
match value {
30+
enum_variant_hidden_from_public_api::AddedVariant::First => (),
31+
enum_variant_hidden_from_public_api::AddedVariant::Second => (),
32+
}'''

0 commit comments

Comments
 (0)