Skip to content

Commit ef02b2d

Browse files
authored
Add the type_allows_fewer_const_generic_params lint. (#1054)
It catches structs/enums/unions that no longer support the previous number of const generic parameters.
1 parent 6b429d8 commit ef02b2d

File tree

7 files changed

+177
-0
lines changed

7 files changed

+177
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
SemverQuery(
2+
id: "type_allows_fewer_const_generic_params",
3+
human_readable_name: "type now allows fewer const generic parameters",
4+
description: "A type now allows fewer const generic parameters than before.",
5+
required_update: Major,
6+
lint_level: Deny,
7+
reference_link: Some("https://doc.rust-lang.org/reference/items/generics.html#const-generics"),
8+
query: r#"
9+
{
10+
CrateDiff {
11+
baseline {
12+
item {
13+
... on ImplOwner {
14+
visibility_limit @filter(op: "=", value: ["$public"])
15+
name @output
16+
owner_type: __typename @tag @output
17+
18+
importable_path {
19+
path @tag @output
20+
public_api @filter(op: "=", value: ["$true"])
21+
}
22+
23+
generic_parameter @fold
24+
@transform(op: "count")
25+
@tag(name: "old_allowed_const_count")
26+
@output(name: "old_allowed_const_count") {
27+
... on GenericConstParameter {
28+
old_allowed_consts: name @output
29+
}
30+
}
31+
}
32+
}
33+
}
34+
current {
35+
item {
36+
... on ImplOwner {
37+
visibility_limit @filter(op: "=", value: ["$public"]) @output
38+
__typename @filter(op: "=", value: ["%owner_type"])
39+
40+
importable_path {
41+
path @filter(op: "=", value: ["%path"])
42+
public_api @filter(op: "=", value: ["$true"])
43+
}
44+
45+
generic_parameter @fold
46+
@transform(op: "count")
47+
@filter(op: "<", value: ["%old_allowed_const_count"])
48+
@output(name: "new_allowed_const_count") {
49+
... on GenericConstParameter {
50+
new_allowed_consts: name @output
51+
}
52+
}
53+
54+
span_: span @optional {
55+
filename @output
56+
begin_line @output
57+
}
58+
}
59+
}
60+
}
61+
}
62+
}"#,
63+
arguments: {
64+
"public": "public",
65+
"true": true,
66+
},
67+
error_message: "A type now allows fewer const generic parameters than it used to. Uses of this type that supplied all previously-supported const generics will be broken.",
68+
per_result_error_template: Some("{{owner_type}} {{name}} allows {{old_allowed_const_count}} -> {{new_allowed_const_count}} const generics in {{span_filename}}:{{span_begin_line}}"),
69+
// TODO: see https://github.com/obi1kenobi/cargo-semver-checks/blob/main/CONTRIBUTING.md#adding-a-witness
70+
// for information about this field.
71+
//
72+
// The witness would be a type ascription with the old number
73+
// of allowed const generics (including ones that provided default values),
74+
// which will be too many generics for the new definition.
75+
witness: None,
76+
)

src/query.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,7 @@ add_lints!(
12181218
trait_unsafe_added,
12191219
trait_unsafe_removed,
12201220
tuple_struct_to_plain_struct,
1221+
type_allows_fewer_const_generic_params,
12211222
type_marked_deprecated,
12221223
type_mismatched_generic_lifetimes,
12231224
type_requires_more_const_generic_params,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
publish = false
3+
name = "type_allows_fewer_const_generic_params"
4+
version = "0.1.0"
5+
edition = "2021"
6+
7+
[dependencies]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pub struct Example<const N: usize> {
2+
data: [i64; N],
3+
}
4+
5+
pub enum NotGenericAnymore {
6+
First([i64; 16]),
7+
}
8+
9+
pub union NotGenericEither<T> {
10+
left: std::mem::ManuallyDrop<[T; 4]>,
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
publish = false
3+
name = "type_allows_fewer_const_generic_params"
4+
version = "0.1.0"
5+
edition = "2021"
6+
7+
[dependencies]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
pub struct Example<const N: usize, const M: usize = 8> {
2+
data: [i64; N],
3+
data2: [i64; M],
4+
}
5+
6+
pub enum NotGenericAnymore<const N: usize> {
7+
First([i64; N]),
8+
}
9+
10+
pub union NotGenericEither<T, const N: usize> {
11+
left: std::mem::ManuallyDrop<[T; N]>,
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
source: src/query.rs
3+
expression: "&query_execution_results"
4+
snapshot_kind: text
5+
---
6+
{
7+
"./test_crates/type_allows_fewer_const_generic_params/": [
8+
{
9+
"name": String("Example"),
10+
"new_allowed_const_count": Uint64(1),
11+
"new_allowed_consts": List([
12+
String("N"),
13+
]),
14+
"old_allowed_const_count": Uint64(2),
15+
"old_allowed_consts": List([
16+
String("N"),
17+
String("M"),
18+
]),
19+
"owner_type": String("Struct"),
20+
"path": List([
21+
String("type_allows_fewer_const_generic_params"),
22+
String("Example"),
23+
]),
24+
"span_begin_line": Uint64(1),
25+
"span_filename": String("src/lib.rs"),
26+
"visibility_limit": String("public"),
27+
},
28+
{
29+
"name": String("NotGenericAnymore"),
30+
"new_allowed_const_count": Uint64(0),
31+
"new_allowed_consts": List([]),
32+
"old_allowed_const_count": Uint64(1),
33+
"old_allowed_consts": List([
34+
String("N"),
35+
]),
36+
"owner_type": String("Enum"),
37+
"path": List([
38+
String("type_allows_fewer_const_generic_params"),
39+
String("NotGenericAnymore"),
40+
]),
41+
"span_begin_line": Uint64(5),
42+
"span_filename": String("src/lib.rs"),
43+
"visibility_limit": String("public"),
44+
},
45+
{
46+
"name": String("NotGenericEither"),
47+
"new_allowed_const_count": Uint64(0),
48+
"new_allowed_consts": List([]),
49+
"old_allowed_const_count": Uint64(1),
50+
"old_allowed_consts": List([
51+
String("N"),
52+
]),
53+
"owner_type": String("Union"),
54+
"path": List([
55+
String("type_allows_fewer_const_generic_params"),
56+
String("NotGenericEither"),
57+
]),
58+
"span_begin_line": Uint64(9),
59+
"span_filename": String("src/lib.rs"),
60+
"visibility_limit": String("public"),
61+
},
62+
],
63+
}

0 commit comments

Comments
 (0)