-
-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
intial draft of struct_without_pub_fields_changed
- Loading branch information
1 parent
868b095
commit 5b5ab32
Showing
11 changed files
with
342 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
SemverQuery( | ||
id: "struct_with_no_pub_fields_changed", | ||
human_readable_name: "public API struct with no public fields is no longer a struct", | ||
description: "A struct without pub fields was converted into an enum or union, breaking pattern matching.", | ||
required_update: Major, | ||
lint_level: Deny, | ||
reference_link: Some("https://internals.rust-lang.org/t/rest-patterns-foo-should-match-non-struct-types/21607"), | ||
reference: Some( | ||
r#"\ | ||
Even if a structs does not expose pub fields, pattern matching like `matches!(value, Example { .. })` is accessible outside their defining crate. \ | ||
Changing such a struct to make it an enum or union will break this pattern match, as their syntax is different. | ||
More info: https://github.com/obi1kenobi/cargo-semver-checks/issues/954 | ||
"# | ||
), | ||
query: r#" | ||
{ | ||
CrateDiff { | ||
baseline { | ||
item { | ||
... on Struct { | ||
struct_typename: __typename @tag @output | ||
visibility_limit @filter(op: "=", value: ["$public"]) @output | ||
struct_type @output | ||
# Ensure the struct does not have pub fields to prevent overlap with struct_with_pub_fields_changed | ||
field @fold @transform(op: "count") @filter(op: "=", value: ["$zero"]) { | ||
visibility_limit @filter(op: "=", value: ["$public"]) | ||
public_api_eligible @filter(op: "=", value: ["$true"]) | ||
} | ||
# Ensure the struct does have non-pub fields to prevent overlap with constructible_struct_changed_type | ||
field @fold @transform(op: "count") @filter(op: ">", value: ["$zero"]) { | ||
visibility_limit @filter(op: "!=", value: ["$public"]) | ||
} | ||
importable_path { | ||
path @output @tag | ||
public_api @filter(op: "=", value: ["$true"]) | ||
} | ||
} | ||
} | ||
} | ||
current { | ||
item { | ||
... on ImplOwner { | ||
current_typename: __typename @filter(op: "!=", value: ["%struct_typename"]) | ||
@output | ||
visibility_limit @filter(op: "=", value: ["$public"]) | ||
name @output | ||
importable_path { | ||
path @filter(op: "=", value: ["%path"]) | ||
public_api @filter(op: "=", value: ["$true"]) | ||
} | ||
span_: span @optional { | ||
filename @output | ||
begin_line @output | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}"#, | ||
arguments: { | ||
"public": "public", | ||
"true": true, | ||
"zero": 0, | ||
}, | ||
error_message: "A struct without pub fields became an enum or union, breaking pattern matching.", | ||
per_result_error_template: Some("struct {{join \"::\" path}} became {{lowercase current_typename}} in file {{span_filename}}:{{span_begin_line}}"), | ||
witness: ( | ||
hint_template: r#"matches!(value, {{join "::" path}}{...});"#, | ||
witness_template: r#"matches!(value, {{join "::" path}}::Variant);"#, | ||
), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
publish = false | ||
name = "struct_with_no_pub_fields_changed" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] |
46 changes: 46 additions & 0 deletions
46
test_crates/struct_with_no_pub_fields_changed/new/src/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
pub enum PubStructChangedEnum { | ||
Foo, | ||
} | ||
|
||
pub union PubStructChangedUnion { | ||
foo: usize | ||
} | ||
|
||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// This is `struct_missing` instead | ||
pub type PubStructChangedType = u8; | ||
|
||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// This is `constructible_struct_changed_type` instead | ||
pub enum PubStructChangedNoFieldsEnum {} | ||
|
||
/// This struct should not be reported by the `struct_pub_field_missing` rule: | ||
/// since the struct is not pub in the first place, changing it does not change the API | ||
enum NonPubStructChangedEnum { | ||
Foo, | ||
} | ||
|
||
/// This struct should not be reported by the `struct_pub_field_missing` rule: | ||
/// since the struct is not pub in the first place, changing it does not change the API | ||
union NonPubStructChangedUnion { | ||
foo: usize | ||
} | ||
|
||
type NonPubStructChangedType = u8; | ||
|
||
mod not_pub_visible { | ||
/// This struct should not be reported by the `struct_pub_field_missing` rule: | ||
/// since the struct is not in a pub module, changing it does not change the API | ||
pub enum NonReachabgeStructChangedEnum { | ||
Foo, | ||
} | ||
/// This struct should not be reported by the `struct_pub_field_missing` rule: | ||
/// since the struct is not in a pub module, changing it does not change the API | ||
pub union NonReachabgeStructChangedUnion { | ||
foo: usize | ||
} | ||
/// This struct should not be reported by the `struct_pub_field_missing` rule: | ||
/// since the struct is not in a pub module, changing it does not change the API | ||
pub type NonReachabgeStructChangedType = u8; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
publish = false | ||
name = "struct_with_no_pub_fields_changed" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] |
48 changes: 48 additions & 0 deletions
48
test_crates/struct_with_no_pub_fields_changed/old/src/lib.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
pub struct PubStructChangedEnum { | ||
foo: usize, | ||
} | ||
|
||
pub struct PubStructChangedUnion { | ||
foo: usize, | ||
} | ||
|
||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// This is `struct_missing` instead | ||
pub struct PubStructChangedType(u8); | ||
|
||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// This is `constructible_struct_changed_type` instead | ||
pub struct PubStructChangedNoFieldsEnum {} | ||
|
||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// since the struct is not pub in the first place, changing it does not change the API | ||
struct NonPubStructChangedEnum { | ||
foo: usize, | ||
} | ||
|
||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// since the struct is not pub in the first place, changing it does not change the API | ||
struct NonPubStructChangedUnion { | ||
foo: usize, | ||
} | ||
|
||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// since the struct is not pub in the first place, changing it does not change the API | ||
struct NonPubStructChangedType(u8); | ||
|
||
mod not_pub_visible { | ||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// since the struct is not in a pub module, changing it does not change the API | ||
pub struct NonReachabgeStructChangedEnum { | ||
foo: usize, | ||
} | ||
/// This struct should not be reported by the `struct_with_no_pub_fields_changed` rule: | ||
/// since the struct is not in a pub module, changing it does not change the API | ||
pub struct NonReachabgeStructChangedUnion { | ||
foo: usize, | ||
} | ||
/// This struct should not be reported by the `struct_pub_field_missing` rule: | ||
/// since the struct is not in a pub module, changing it does not change the API | ||
pub struct NonReachabgeStructChangedType(u8); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
test_outputs/query_execution/struct_with_no_pub_fields_changed.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
--- | ||
source: src/query.rs | ||
expression: "&query_execution_results" | ||
--- | ||
{ | ||
"./test_crates/inherent_method_must_use_added/": [ | ||
{ | ||
"current_typename": String("Enum"), | ||
"name": String("StructToEnumWithMustUseMethods"), | ||
"path": List([ | ||
String("inherent_method_must_use_added"), | ||
String("item_type_changed_inherent_method_must_use_added"), | ||
String("StructToEnumWithMustUseMethods"), | ||
]), | ||
"span_begin_line": Uint64(68), | ||
"span_filename": String("src/item_type_changed_inherent_method_must_use_added.rs"), | ||
"struct_type": String("plain"), | ||
"struct_typename": String("Struct"), | ||
"visibility_limit": String("public"), | ||
}, | ||
{ | ||
"current_typename": String("Union"), | ||
"name": String("StructToUnionWithMustUseMethods"), | ||
"path": List([ | ||
String("inherent_method_must_use_added"), | ||
String("item_type_changed_inherent_method_must_use_added"), | ||
String("StructToUnionWithMustUseMethods"), | ||
]), | ||
"span_begin_line": Uint64(99), | ||
"span_filename": String("src/item_type_changed_inherent_method_must_use_added.rs"), | ||
"struct_type": String("plain"), | ||
"struct_typename": String("Struct"), | ||
"visibility_limit": String("public"), | ||
}, | ||
], | ||
"./test_crates/struct_becomes_enum/": [ | ||
{ | ||
"current_typename": String("Enum"), | ||
"name": String("TupleToEnum"), | ||
"path": List([ | ||
String("struct_becomes_enum"), | ||
String("TupleToEnum"), | ||
]), | ||
"span_begin_line": Uint64(45), | ||
"span_filename": String("src/lib.rs"), | ||
"struct_type": String("tuple"), | ||
"struct_typename": String("Struct"), | ||
"visibility_limit": String("public"), | ||
}, | ||
{ | ||
"current_typename": String("Enum"), | ||
"name": String("StructToEnum"), | ||
"path": List([ | ||
String("struct_becomes_enum"), | ||
String("StructToEnum"), | ||
]), | ||
"span_begin_line": Uint64(61), | ||
"span_filename": String("src/lib.rs"), | ||
"struct_type": String("plain"), | ||
"struct_typename": String("Struct"), | ||
"visibility_limit": String("public"), | ||
}, | ||
], | ||
"./test_crates/struct_with_no_pub_fields_changed/": [ | ||
{ | ||
"current_typename": String("Enum"), | ||
"name": String("PubStructChangedEnum"), | ||
"path": List([ | ||
String("struct_with_no_pub_fields_changed"), | ||
String("PubStructChangedEnum"), | ||
]), | ||
"span_begin_line": Uint64(1), | ||
"span_filename": String("src/lib.rs"), | ||
"struct_type": String("plain"), | ||
"struct_typename": String("Struct"), | ||
"visibility_limit": String("public"), | ||
}, | ||
{ | ||
"current_typename": String("Union"), | ||
"name": String("PubStructChangedUnion"), | ||
"path": List([ | ||
String("struct_with_no_pub_fields_changed"), | ||
String("PubStructChangedUnion"), | ||
]), | ||
"span_begin_line": Uint64(5), | ||
"span_filename": String("src/lib.rs"), | ||
"struct_type": String("plain"), | ||
"struct_typename": String("Struct"), | ||
"visibility_limit": String("public"), | ||
}, | ||
], | ||
} |
34 changes: 34 additions & 0 deletions
34
test_outputs/witnesses/struct_with_no_pub_fields_changed.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
source: src/query.rs | ||
description: "Lint `struct_with_no_pub_fields_changed` did not have the expected witness output.\nSee https://github.com/obi1kenobi/cargo-semver-checks/blob/main/CONTRIBUTING.md#testing-witnesses\nfor more information." | ||
expression: "&actual_witnesses" | ||
--- | ||
[["./test_crates/inherent_method_must_use_added/"]] | ||
filename = 'src/item_type_changed_inherent_method_must_use_added.rs' | ||
begin_line = 68 | ||
hint = 'matches!(value, inherent_method_must_use_added::item_type_changed_inherent_method_must_use_added::StructToEnumWithMustUseMethods{...});' | ||
|
||
[["./test_crates/inherent_method_must_use_added/"]] | ||
filename = 'src/item_type_changed_inherent_method_must_use_added.rs' | ||
begin_line = 99 | ||
hint = 'matches!(value, inherent_method_must_use_added::item_type_changed_inherent_method_must_use_added::StructToUnionWithMustUseMethods{...});' | ||
|
||
[["./test_crates/struct_becomes_enum/"]] | ||
filename = 'src/lib.rs' | ||
begin_line = 45 | ||
hint = 'matches!(value, struct_becomes_enum::TupleToEnum{...});' | ||
|
||
[["./test_crates/struct_becomes_enum/"]] | ||
filename = 'src/lib.rs' | ||
begin_line = 61 | ||
hint = 'matches!(value, struct_becomes_enum::StructToEnum{...});' | ||
|
||
[["./test_crates/struct_with_no_pub_fields_changed/"]] | ||
filename = 'src/lib.rs' | ||
begin_line = 1 | ||
hint = 'matches!(value, struct_with_no_pub_fields_changed::PubStructChangedEnum{...});' | ||
|
||
[["./test_crates/struct_with_no_pub_fields_changed/"]] | ||
filename = 'src/lib.rs' | ||
begin_line = 5 | ||
hint = 'matches!(value, struct_with_no_pub_fields_changed::PubStructChangedUnion{...});' |