@neralabs/rerail-pack-rust 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -21
- package/licenses/clippy/UPSTREAM.md +1 -1
- package/pack.json +116 -2
- package/package.json +1 -1
- package/rules/clippy-builtin-type-shadow.json +13 -0
- package/rules/clippy-inconsistent-digit-grouping.json +40 -0
- package/rules/clippy-int-plus-one.json +36 -0
- package/rules/clippy-large-digit-groups.json +28 -0
- package/rules/clippy-many-single-char-names.json +30 -0
- package/rules/clippy-mixed-case-hex-literals.json +1 -0
- package/rules/clippy-needless-arbitrary-self-type.json +12 -0
- package/rules/clippy-needless-else.json +15 -0
- package/rules/clippy-needless-raw-string-hashes.json +20 -0
- package/rules/clippy-octal-escapes.json +24 -0
- package/rules/clippy-partial-pub-fields.json +50 -0
- package/rules/clippy-precedence-bits.json +105 -0
- package/rules/clippy-precedence.json +25 -0
- package/rules/clippy-redundant-at-rest-pattern.json +11 -0
- package/rules/clippy-single-component-path-imports.json +36 -0
- package/rules/clippy-unneeded-wildcard-pattern.json +18 -0
- package/rules/clippy-unusual-byte-groupings.json +27 -0
- package/rules/clippy-zero-prefixed-literal.json +1 -0
package/README.md
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
# Rerail rule pack: Rust
|
|
2
2
|
|
|
3
|
-
Ports of 34 Clippy 0.1.99 lints
|
|
3
|
+
Ports of 34 Clippy 0.1.99 lints. Eighteen pass the [port readiness gates](../../docs/port-readiness.md) and ship in `rules/` and `pack.json`: `clippy-builtin-type-shadow`, `clippy-inconsistent-digit-grouping`, `clippy-int-plus-one`, `clippy-large-digit-groups`, `clippy-many-single-char-names`, `clippy-mixed-case-hex-literals`, `clippy-needless-arbitrary-self-type`, `clippy-needless-else`, `clippy-needless-raw-string-hashes`, `clippy-octal-escapes`, `clippy-partial-pub-fields`, `clippy-precedence`, `clippy-precedence-bits`, `clippy-redundant-at-rest-pattern`, `clippy-single-component-path-imports`, `clippy-unneeded-wildcard-pattern`, `clippy-unusual-byte-groupings` and `clippy-zero-prefixed-literal`. Clippy's default lint levels leave `large_digit_groups`, `many_single_char_names` and `needless_raw_string_hashes` (pedantic) and `partial_pub_fields` and `precedence_bits` (restriction) off, so they ship off (`"on": false`). The other 16 are candidates in `candidates/rules/`, judged by the same gates without blocking; the four that port a non-default `clippy.toml` (`-threshold`, `-no-fractions`, `-one-allowed`) stay candidates whatever they score, since the gates judge them against Clippy's defaults. Each port is scored against Clippy's recorded findings on its UI tests and on pinned ripgrep and tokio checkouts, through the engine's production workspace path, with its disagreements declared in `divergences.json` (214 entries, each with its evidence); the candidate `clippy-option-env-unwrap`'s two on `tests/ui/option_env_unwrap.rs` (an `external!` proc macro that rewrites its tokens' spans, which syntax alone cannot tell from a span-keeping macro) are the only ones left undeclared.
|
|
4
4
|
|
|
5
5
|
This pack follows the [pack structure and validation contract](../../docs/pack-format.md) and is checked by `npx vitest run test/engine/catalog/packs.test.ts`.
|
|
6
6
|
|
|
7
7
|
| Path | What |
|
|
8
8
|
|---|---|
|
|
9
|
-
| `pack.json` | The pack (`rerail.rule-pack/v1`): its match definition, and
|
|
10
|
-
| `
|
|
9
|
+
| `pack.json` | The pack (`rerail.rule-pack/v1`): its match definition, and each shipped rule's document, title, group and whether it is on |
|
|
10
|
+
| `rules/` | The code-rule documents (`rerail.policy/v1`) of the ports that pass the port readiness gates |
|
|
11
|
+
| `candidates/rules/` | The code-rule documents of the other ports, scored and judged but never shipped |
|
|
11
12
|
| `conformance.json` | Each ported lint's upstream tool and rule, how findings compare, and the capabilities it exercises; the pinned Clippy tool and corpora |
|
|
12
13
|
| `divergences.json` | Declared disagreements with Clippy |
|
|
13
|
-
| `upstream/clippy/` | Clippy's copied UI tests, the probes Rerail wrote (`fixtures/rerail/`, listed in `UPSTREAM.md`), recordings and recorder (`generate.py`, sharing `upstream/common.py`) |
|
|
14
|
+
| `upstream/clippy/` | Clippy's copied UI tests, the probes Rerail wrote (`fixtures/rerail/`, listed in `UPSTREAM.md`), recordings and recorder (`generate.py`, sharing `upstream/common.py`); the port readiness gates' `gates.yaml`, `recording.lock` and `goldens.tsv` |
|
|
14
15
|
| `licenses/clippy/` | Clippy's licence and `UPSTREAM.md`, listing every copied file |
|
|
15
16
|
|
|
16
17
|
## Scores
|
|
17
18
|
|
|
18
|
-
Every port
|
|
19
|
+
Every port, shipped or candidate, is scored here. Scored with `node --import tsx conformance/languages/cli.ts --pack rust` (Clippy 0.1.99, Rust 1.99.0; fixtures and both
|
|
19
20
|
corpora). FP and FN count unexplained points only; an explained point is one a divergence names, and recall counts
|
|
20
21
|
an explained FN against the pack.
|
|
21
22
|
|
|
22
23
|
| Source | Rules | TP | FP | FN | Explained FP | Explained FN |
|
|
23
24
|
|---|---|---|---|---|---|---|
|
|
24
|
-
| fixtures (Clippy's UI tests and Rerail's probes) | 34 |
|
|
25
|
+
| fixtures (Clippy's UI tests and Rerail's probes) | 34 | 397 | 2 | 2 | 0 | 7 |
|
|
25
26
|
| ripgrep corpus | 34 | 614 | 0 | 0 | 11 | 6 |
|
|
26
|
-
| tokio corpus | 34 |
|
|
27
|
+
| tokio corpus | 34 | 555 | 0 | 0 | 98 | 95 |
|
|
27
28
|
|
|
28
29
|
Divergences by kind (`divergences.json`):
|
|
29
30
|
|
|
30
31
|
| Kind | fixtures | ripgrep | tokio | Total | What |
|
|
31
32
|
|---|---|---|---|---|---|
|
|
32
|
-
| `rerail-unknown` |
|
|
33
|
+
| `rerail-unknown` | 7 | 2 | 90 | 99 | Code tree-sitter-rust holds as macro token trees or `macro_rules!` bodies, which Clippy lints after expansion; `box` patterns tree-sitter-rust does not parse; an attribute on a tuple element expression; a decimal literal at or above 2^53, which a rule's JSON-number bounds cannot name |
|
|
33
34
|
| `not-comparable` | 0 | 15 | 100 | 115 | Items and files a `cfg` leaves out of the recording's build (macOS, `--all-features`, no `tokio_unstable`, `loom`, `docsrs` or `miri`), `cfg_attr` levels whose predicate is false there, `#[tokio::test]`'s expansion, grep-index's crate-root `#![allow(warnings)]` (read per file), and the ui-toml variants on corpora recorded with Clippy's defaults |
|
|
34
35
|
| `upstream-wrong` | 0 | 0 | 0 | 0 | |
|
|
35
36
|
|
|
@@ -38,8 +39,8 @@ Per rule (TP / FP / FN, explained points in parentheses):
|
|
|
38
39
|
| Rule | fixtures | ripgrep | tokio |
|
|
39
40
|
|---|---|---|---|
|
|
40
41
|
| `clippy-precedence` | 30 / 0 / 0 | 0 / 0 / 0 | 0 / 0 / 0 |
|
|
41
|
-
| `clippy-precedence-bits` |
|
|
42
|
-
| `clippy-double-parens` |
|
|
42
|
+
| `clippy-precedence-bits` | 26 / 0 / 0 | 0 / 0 / 0 | 4 / 0 / 0 |
|
|
43
|
+
| `clippy-double-parens` | 24 / 0 / 0 (1) | 0 / 0 / 0 | 0 / 0 / 0 |
|
|
43
44
|
| `clippy-int-plus-one` | 14 / 0 / 0 | 0 / 0 / 0 | 0 / 0 / 0 |
|
|
44
45
|
| `clippy-redundant-static-lifetimes` | 31 / 0 / 0 | 32 / 0 / 0 (2) | 0 / 0 / 0 |
|
|
45
46
|
| `clippy-needless-arbitrary-self-type` | 9 / 0 / 0 | 0 / 0 / 0 | 0 / 0 / 0 |
|
|
@@ -49,7 +50,7 @@ Per rule (TP / FP / FN, explained points in parentheses):
|
|
|
49
50
|
| `clippy-redundant-at-rest-pattern` | 6 / 0 / 0 | 0 / 0 / 0 | 0 / 0 / 0 |
|
|
50
51
|
| `clippy-needless-else` | 1 / 0 / 0 | 0 / 0 / 0 | 0 / 0 / 0 |
|
|
51
52
|
| `clippy-unnested-or-patterns` | 32 / 0 / 0 (3) | 4 / 0 / 0 | 1 / 0 / 0 |
|
|
52
|
-
| `clippy-option-env-unwrap` |
|
|
53
|
+
| `clippy-option-env-unwrap` | 5 / 2 / 2 | 0 / 0 / 0 | 0 / 0 / 0 |
|
|
53
54
|
| `clippy-unreadable-literal` | 16 / 0 / 0 | 5 / 0 / 0 (1) | 0 / 0 / 0 (1) |
|
|
54
55
|
| `clippy-unreadable-literal-no-fractions` | 1 / 0 / 0 | 5 / 0 / 0 (1) | 0 / 0 / 0 (1) |
|
|
55
56
|
| `clippy-inconsistent-digit-grouping` | 9 / 0 / 0 | 0 / 0 / 0 | 0 / 0 / 0 |
|
|
@@ -74,11 +75,19 @@ Per rule (TP / FP / FN, explained points in parentheses):
|
|
|
74
75
|
|
|
75
76
|
## Recording and scoring
|
|
76
77
|
|
|
77
|
-
Re-recording
|
|
78
|
+
Re-recording is a maintainer deriving the pack's test data from its pins and archiving it
|
|
79
|
+
([CONTRIBUTING.md](../../CONTRIBUTING.md#pack-test-data)); it is never committed. The recipe
|
|
80
|
+
(`scripts/pack-data/recipes/rust.ts`) runs `upstream/clippy/generate.py` against Clippy 0.1.99 and Rust 1.99.0
|
|
81
|
+
(installed with `rustup`), in `fixtures` mode and then `corpus` mode over ripgrep and tokio. Derive it on Linux, as the
|
|
82
|
+
bump workflow does: tokio has `#[cfg(target_os = "linux")]` code, so `corpus-tokio.expected.json` derived on macOS
|
|
83
|
+
differs. The same holds for the port readiness recordings; a pull request's CI legs record them on Linux and upload
|
|
84
|
+
them as the artifact `recordings-rust--clippy` ([CONTRIBUTING.md](../../CONTRIBUTING.md#merging-maintainers)).
|
|
85
|
+
The probes Rerail wrote (`fixtures/rerail/`) are authored: a change to them goes in your pull request with
|
|
86
|
+
`git add -f`.
|
|
78
87
|
|
|
79
88
|
```sh
|
|
80
|
-
|
|
81
|
-
|
|
89
|
+
npm run fixtures:derive -- --pack rust
|
|
90
|
+
npm run fixtures:push -- --pack rust # on your own branch: archive it and rewrite its test-data.lock
|
|
82
91
|
```
|
|
83
92
|
|
|
84
93
|
Scoring one rule with every false positive and false negative printed:
|
|
@@ -87,6 +96,15 @@ Scoring one rule with every false positive and false negative printed:
|
|
|
87
96
|
node --import tsx conformance/languages/cli.ts --pack rust --rule clippy-precedence --fixtures
|
|
88
97
|
```
|
|
89
98
|
|
|
99
|
+
The port readiness gates judge every port against their own recording of Clippy (`upstream/clippy/recording.lock`;
|
|
100
|
+
the recorder runs the rustup toolchain `conformance/recorders/port-readiness/runtimes/clippy-1.99.0/` pins, on the
|
|
101
|
+
same UI tests and corpora, as `generate.py` does):
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
npm run port-readiness:record -- --pack rust --tool clippy # needs rustup, git and the network
|
|
105
|
+
npm run port-readiness -- --pack rust --tool clippy
|
|
106
|
+
```
|
|
107
|
+
|
|
90
108
|
## Rule details
|
|
91
109
|
|
|
92
110
|
What each rule matches beyond its one-line description: exact matching, edge cases, upstream settings and known divergences.
|
|
@@ -97,19 +115,27 @@ Port of Clippy 0.1.99's allow_attributes: reports the path of every outer #[allo
|
|
|
97
115
|
|
|
98
116
|
### `clippy-allow-attributes-without-reason`
|
|
99
117
|
|
|
100
|
-
Port of Clippy 0.1.99's allow_attributes_without_reason: reports every #[allow(..)] and #[expect(..)] attribute, inner or outer, one a #[cfg_attr(..)] expands to included (at the expanded attribute), whose last item is not `reason = ".."`. The lint needs Rust 1.81 (lint reasons, `suppress.clippy.msrv`). What a macro invocation's or macro_rules! body's token tree holds, and whether a #[cfg] predicate holds in a build, are not read. A #[cfg_attr] is read as active unless its first argument is exactly `test`, `any()` or `not(clippy)`, the predicates the suppression engine reads as off whatever the build; every other predicate is read as active. Each allow or expect a #[cfg_attr] expands to is checked on its own for a last `reason = ".."` item.
|
|
118
|
+
Port of Clippy 0.1.99's allow_attributes_without_reason: reports every #[allow(..)] and #[expect(..)] attribute, inner or outer, one a #[cfg_attr(..)] expands to included (at the expanded attribute), whose last item is not `reason = ".."`. The lint needs Rust 1.81 (lint reasons, `suppress.clippy.msrv`). What a macro invocation's or macro_rules! body's token tree holds, and whether a #[cfg] predicate holds in a build, are not read. A #[cfg_attr] is read as active unless its first argument is exactly `test`, `any()` or `not(clippy)`, the predicates the suppression engine reads as off whatever the build; every other predicate is read as active. Each allow or expect a #[cfg_attr] expands to is checked on its own for a last `reason = ".."` item and reported at its own span (`allow(..)`, as Clippy reports the expanded attribute); a list nested deeper than two parentheses inside it is not read.
|
|
119
|
+
|
|
120
|
+
### `clippy-builtin-type-shadow`
|
|
121
|
+
|
|
122
|
+
Port of Clippy 0.1.99's builtin_type_shadow: reports generic type parameters named like a primitive type (rustc's PrimTy names: the integer types, the float types f16 to f128, bool, char and str); semantic name resolution is not modelled.
|
|
101
123
|
|
|
102
124
|
### `clippy-decimal-literal-representation`
|
|
103
125
|
|
|
104
|
-
Port of Clippy 0.1.99's decimal_literal_representation (literal-representation-threshold 16384, the default): reports a decimal integer literal whose value is at least the threshold and whose hexadecimal digits are a power of two with a margin (1, 2, 4 or 8 then zeros, or 1, 3, 7 or F then Fs, the last digit free) or only 0s and Fs after a leading 7 or F. Values of 2^
|
|
126
|
+
Port of Clippy 0.1.99's decimal_literal_representation (literal-representation-threshold 16384, the default): reports a decimal integer literal whose value is at least the threshold and whose hexadecimal digits (four or more above this threshold) are a power of two with a margin (1, 2, 4 or 8 then zeros, or 1, 3, 7 or F then Fs, the last digit free: a value at most 16 below or 15 above a power of two) or only 0s and Fs after a leading 7 or F (every hexadecimal digit 0 or F, the leading one possibly 7). Values of 2^53 and above are not read: the rule language has no hexadecimal reading of a value, so the digits are read as value ranges and bit masks, and a rule's numbers reach the engine as JavaScript numbers, exact only up to 2^53. Macro arguments and macro_rules! bodies are token trees no syntax-level reader expands.
|
|
105
127
|
|
|
106
128
|
### `clippy-decimal-literal-representation-threshold`
|
|
107
129
|
|
|
108
|
-
Port of Clippy 0.1.99's decimal_literal_representation under literal-representation-threshold = 0xFFFFFF (its ui-toml test): reports a decimal integer literal whose value is at least the threshold and whose hexadecimal digits are a power of two with a margin (1, 2, 4 or 8 then zeros, or 1, 3, 7 or F then Fs, the last digit free) or only 0s and Fs after a leading 7 or F. Values of 2^
|
|
130
|
+
Port of Clippy 0.1.99's decimal_literal_representation under literal-representation-threshold = 0xFFFFFF (its ui-toml test): reports a decimal integer literal whose value is at least the threshold and whose hexadecimal digits (four or more above this threshold) are a power of two with a margin (1, 2, 4 or 8 then zeros, or 1, 3, 7 or F then Fs, the last digit free: a value at most 16 below or 15 above a power of two) or only 0s and Fs after a leading 7 or F (every hexadecimal digit 0 or F, the leading one possibly 7). Values of 2^53 and above are not read: the rule language has no hexadecimal reading of a value, so the digits are read as value ranges and bit masks, and a rule's numbers reach the engine as JavaScript numbers, exact only up to 2^53. Macro arguments and macro_rules! bodies are token trees no syntax-level reader expands.
|
|
109
131
|
|
|
110
132
|
### `clippy-double-parens`
|
|
111
133
|
|
|
112
|
-
Port of Clippy 0.1.99's double_parens lint: reports redundant nested parentheses around an expression (only whitespace between the two opening or closing parentheses, as Clippy's source check requires; a call's sole argument in parentheses, reported once where the nested-parentheses clauses already report the same span);
|
|
134
|
+
Port of Clippy 0.1.99's double_parens lint: reports redundant nested parentheses around an expression (only whitespace between the two opening or closing parentheses, as Clippy's source check requires; a call's sole argument in parentheses, reported once where the nested-parentheses clauses already report the same span), and the same two shapes in a macro_rules! transcriber's tokens (a parenthesized group whose only content is another parenthesized group, in expression position after `=`, `=>`, `return`, a delimiter, `;` or `,`, or as the sole parenthesized argument after a call's name; a `$(` repetition is not a parenthesized expression); expansion of macro invocations' arguments and tuple/unit argument semantics are not modelled.
|
|
135
|
+
|
|
136
|
+
### `clippy-else-if-without-else`
|
|
137
|
+
|
|
138
|
+
Port of Clippy 0.1.99's else_if_without_else lint: reports the if expression of an else-if branch whose final if has no else, spanning the whole else-if expression; macro expansion and cfg evaluation are not modelled.
|
|
113
139
|
|
|
114
140
|
### `clippy-inconsistent-digit-grouping`
|
|
115
141
|
|
|
@@ -155,17 +181,21 @@ Port of Clippy 0.1.99's needless_raw_strings: reports raw literals whose content
|
|
|
155
181
|
|
|
156
182
|
Port of Clippy 0.1.99's octal_escapes: reports each \0 followed by one or two octal digits in string, byte-string, or C-string literals; format-string preprocessing and external macros are not modelled.
|
|
157
183
|
|
|
184
|
+
### `clippy-option-env-unwrap`
|
|
185
|
+
|
|
186
|
+
Port of Clippy 0.1.99's option_env_unwrap: reports an unwrap or expect call on option_env!, spanning the whole call; inside a token tree (a macro invocation's input or a macro_rules! body) it reports the call where its tokens are written, as Clippy does for macros that keep their input's spans (macro_rules!, format macros) and for a macro_rules! body that is expanded; a proc macro that respans its input, which Clippy reports at the invocation, is not modelled.
|
|
187
|
+
|
|
158
188
|
### `clippy-partial-pub-fields`
|
|
159
189
|
|
|
160
|
-
Port of Clippy 0.1.99's partial_pub_fields: in a struct whose first field is `pub` (exactly: `pub(crate)` and other restricted visibilities are not), reports the first field that is not, and in one whose first field is not `pub`, the first field that is, at the field's visibility (
|
|
190
|
+
Port of Clippy 0.1.99's partial_pub_fields: in a struct whose first field is `pub` (exactly: `pub(crate)` and other restricted visibilities are not), reports the first field that is not, and in one whose first field is not `pub`, the first field that is, at the field's visibility (a zero-width point at the field's start when it has none).
|
|
161
191
|
|
|
162
192
|
### `clippy-precedence`
|
|
163
193
|
|
|
164
|
-
Port of Clippy 0.1.99's precedence lint: reports a shift or bitwise operation whose operand is an unparenthesized arithmetic (+ - * / %) operation, at every nesting depth; macro expansion and type/value semantics are not modelled.
|
|
194
|
+
Port of Clippy 0.1.99's precedence lint: reports a shift or bitwise operation whose operand is an unparenthesized arithmetic (+ - * / %) operation, at every nesting depth, and a method call whose receiver is an unparenthesized closure (spanning the call); macro expansion and type/value semantics are not modelled.
|
|
165
195
|
|
|
166
196
|
### `clippy-precedence-bits`
|
|
167
197
|
|
|
168
|
-
Port of Clippy 0.1.99's precedence_bits lint: reports, at any nesting depth,
|
|
198
|
+
Port of Clippy 0.1.99's precedence_bits lint: reports, at any nesting depth, every bitwise (& | ^) operation with an unparenthesized shift operand and no unparenthesized arithmetic operand (that mix is the precedence lint's), each at its own span, so every operation of a left-nested chain like `a ^ b ^ c >> 1 ^ d >> 2` that has a shift operand is reported; macro expansion and semantic type checks are not modelled.
|
|
169
199
|
|
|
170
200
|
### `clippy-redundant-field-names`
|
|
171
201
|
|
|
@@ -183,6 +213,10 @@ Port of Clippy 0.1.99's single_char_lifetime_names: reports each single-characte
|
|
|
183
213
|
|
|
184
214
|
Port of Clippy 0.1.99's single_component_path_imports (Rust 2018 and later): reports a module's (the file's or a `mod`'s) non-`pub` `use name;` without a rename, and each `name` of a `use {a, b};` without a prefix, unless a `macro_rules!` of that name comes before it in the module, a non-`pub` `use self::name..` of the module (or `use self::{name..}`) names it, or a path `self::name::..` outside `use` declarations does anywhere in the module. Clippy reads the module after macro expansion; macro arguments and macro_rules! bodies are token trees no syntax-level reader expands.
|
|
185
215
|
|
|
216
|
+
### `clippy-unneeded-wildcard-pattern`
|
|
217
|
+
|
|
218
|
+
Port of Clippy 0.1.99's unneeded_wildcard_pattern: reports the run of wildcard elements of a tuple or tuple-struct pattern adjacent to its rest pattern, and the trailing wildcard fields of a struct pattern before its rest, spanning them with their separators up to (or from) the rest pattern as Clippy does; elements nested more than two brackets deep and macro-expanded code are not modelled.
|
|
219
|
+
|
|
186
220
|
### `clippy-unnested-or-patterns`
|
|
187
221
|
|
|
188
222
|
Port of Clippy 0.1.99's unnested_or_patterns: reports a match arm's, let's, if/while let's or parameter's pattern that holds an or-pattern Clippy nests: one with a parenthesised or-pattern among its alternatives, or with two alternatives (adjacent or not) built alike that differ in one sub-pattern at most: `&mut`, the same `x @`, `ref x @` or `mut x @` binding, a tuple, slice or tuple struct (same path) pattern whose differing element is not `..` on either side, among the first six, or a struct pattern (same path, both with or both without `..`, up to six fields in any order) whose other fields are the same, unless the two are the same shorthands only. The lint needs Rust 1.53 (`suppress.clippy.msrv`). Sub-patterns compare by their tokens, parentheses included. Macro arguments and macro_rules! bodies are token trees no syntax-level reader expands; `box` patterns (an unstable feature) do not parse.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Upstream: [rust-lang/rust-clippy](https://github.com/rust-lang/rust-clippy/tree/49e2f89a2605a9a340e04955fdbefa9803e6027a) at tag `rust-1.99.0` (commit `49e2f89a2605a9a340e04955fdbefa9803e6027a`), the clippy shipped as `clippy 0.1.99 (b940084d7e 2026-09-28)` with Rust 1.99.0. License: MIT OR Apache-2.0 (Copyright (c) The Rust Project Contributors); [`LICENSE-MIT`](LICENSE-MIT), [`LICENSE-APACHE`](LICENSE-APACHE) and [`COPYRIGHT`](COPYRIGHT) are the upstream license files, copied verbatim at that tag.
|
|
4
4
|
|
|
5
|
-
The files listed below are UI tests of the clippy lints the Rust pack ports (`packs/rust/conformance.json`), the auxiliary crates those tests build, and the `clippy.toml` files they read. They remain under clippy's license. Every other file under `upstream/clippy/` is Rerail's, under the Apache License 2.0 (this repository's `LICENSE`; `upstream/clippy/UPSTREAM.md` lists the cases under `fixtures/rerail/`): `generate.py`, `../common.py` and the recordings they write by running clippy (`fixtures.expected.json`, `fixtures.upstream-check.json`, `corpus-*.expected.json`).
|
|
5
|
+
The files listed below are UI tests of the clippy lints the Rust pack ports (`packs/rust/conformance.json`), the auxiliary crates those tests build, and the `clippy.toml` files they read. They remain under clippy's license. The rule documents in `rules/` and `candidates/rules/` are Rerail's re-implementations of clippy's lints, published under the pack's licence expression, `Apache-2.0 AND MIT`, as `REUSE.toml` annotates them. Every other file under `upstream/clippy/` is Rerail's, under the Apache License 2.0 (this repository's `LICENSE`; `upstream/clippy/UPSTREAM.md` lists the cases under `fixtures/rerail/`): `generate.py`, `../common.py` and the recordings they write by running clippy (`fixtures.expected.json`, `fixtures.upstream-check.json`, `corpus-*.expected.json`), and the port readiness gates' `gates.yaml`, `recording.lock` and `goldens.tsv`. The port readiness recording itself is not in the tree and holds no clippy test text: it names each test file by path and sha256, and the gates fetch them from rust-clippy at the pinned commit.
|
|
6
6
|
|
|
7
7
|
Paths are relative to `packs/rust/`; each file keeps its upstream path under `upstream/clippy/fixtures/`.
|
|
8
8
|
|
package/pack.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"id": "rust",
|
|
4
4
|
"name": "Rust",
|
|
5
5
|
"category": "language",
|
|
6
|
-
"covers": "
|
|
6
|
+
"covers": "18 Clippy 0.1.99 lints ported to Rerail, 13 of them on and 5 off until turned on, each scored against Clippy's own recorded findings on its UI tests; 16 more ports are candidates until they pass the port readiness gates.",
|
|
7
7
|
"reason": "matches Rust",
|
|
8
8
|
"match": {
|
|
9
9
|
"any": [
|
|
@@ -15,5 +15,119 @@
|
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
},
|
|
18
|
-
"rules": [
|
|
18
|
+
"rules": [
|
|
19
|
+
{
|
|
20
|
+
"id": "clippy-needless-arbitrary-self-type",
|
|
21
|
+
"document": "rules/clippy-needless-arbitrary-self-type.json",
|
|
22
|
+
"title": "Clippy needless_arbitrary_self_type: Type of `self` parameter is already by default `Self`",
|
|
23
|
+
"group": "Clippy"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "clippy-redundant-at-rest-pattern",
|
|
27
|
+
"document": "rules/clippy-redundant-at-rest-pattern.json",
|
|
28
|
+
"title": "Clippy redundant_at_rest_pattern: Checks for `[all @ ..]` where `all` would suffice",
|
|
29
|
+
"group": "Clippy"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "clippy-needless-else",
|
|
33
|
+
"document": "rules/clippy-needless-else.json",
|
|
34
|
+
"title": "Clippy needless_else: Empty else branch",
|
|
35
|
+
"group": "Clippy"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"id": "clippy-octal-escapes",
|
|
39
|
+
"document": "rules/clippy-octal-escapes.json",
|
|
40
|
+
"title": "Clippy octal_escapes: String escape sequences looking like octal characters",
|
|
41
|
+
"group": "Clippy"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "clippy-needless-raw-string-hashes",
|
|
45
|
+
"document": "rules/clippy-needless-raw-string-hashes.json",
|
|
46
|
+
"title": "Clippy needless_raw_string_hashes: Suggests reducing the number of hashes around a raw string literal",
|
|
47
|
+
"group": "Clippy",
|
|
48
|
+
"on": false
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "clippy-single-component-path-imports",
|
|
52
|
+
"document": "rules/clippy-single-component-path-imports.json",
|
|
53
|
+
"title": "Clippy single_component_path_imports: Imports with single component path are redundant",
|
|
54
|
+
"group": "Clippy"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "clippy-many-single-char-names",
|
|
58
|
+
"document": "rules/clippy-many-single-char-names.json",
|
|
59
|
+
"title": "Clippy many_single_char_names: Too many single character bindings",
|
|
60
|
+
"group": "Clippy",
|
|
61
|
+
"on": false
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "clippy-builtin-type-shadow",
|
|
65
|
+
"document": "rules/clippy-builtin-type-shadow.json",
|
|
66
|
+
"title": "Clippy builtin_type_shadow: Shadowing a builtin type",
|
|
67
|
+
"group": "Clippy"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "clippy-inconsistent-digit-grouping",
|
|
71
|
+
"document": "rules/clippy-inconsistent-digit-grouping.json",
|
|
72
|
+
"title": "Clippy inconsistent_digit_grouping: Integer literals with digits grouped inconsistently",
|
|
73
|
+
"group": "Clippy"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"id": "clippy-int-plus-one",
|
|
77
|
+
"document": "rules/clippy-int-plus-one.json",
|
|
78
|
+
"title": "Clippy int_plus_one: Instead of using `x >= y + 1`, use `x > y`",
|
|
79
|
+
"group": "Clippy"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "clippy-large-digit-groups",
|
|
83
|
+
"document": "rules/clippy-large-digit-groups.json",
|
|
84
|
+
"title": "Clippy large_digit_groups: Grouping digits into groups that are too large",
|
|
85
|
+
"group": "Clippy",
|
|
86
|
+
"on": false
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "clippy-mixed-case-hex-literals",
|
|
90
|
+
"document": "rules/clippy-mixed-case-hex-literals.json",
|
|
91
|
+
"title": "Clippy mixed_case_hex_literals: Hex literals whose letter digits are not consistently upper- or lowercased",
|
|
92
|
+
"group": "Clippy"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": "clippy-partial-pub-fields",
|
|
96
|
+
"document": "rules/clippy-partial-pub-fields.json",
|
|
97
|
+
"title": "Clippy partial_pub_fields: Partial fields of a struct are public",
|
|
98
|
+
"group": "Clippy",
|
|
99
|
+
"on": false
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "clippy-precedence",
|
|
103
|
+
"document": "rules/clippy-precedence.json",
|
|
104
|
+
"title": "Clippy precedence: Operations where precedence may be unclear",
|
|
105
|
+
"group": "Clippy"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "clippy-precedence-bits",
|
|
109
|
+
"document": "rules/clippy-precedence-bits.json",
|
|
110
|
+
"title": "Clippy precedence_bits: Operations mixing bit shifting with bit combining/masking",
|
|
111
|
+
"group": "Clippy",
|
|
112
|
+
"on": false
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "clippy-unneeded-wildcard-pattern",
|
|
116
|
+
"document": "rules/clippy-unneeded-wildcard-pattern.json",
|
|
117
|
+
"title": "Clippy unneeded_wildcard_pattern: Tuple and struct patterns with a wildcard pattern (`_`) is next to a rest pattern (`..`)",
|
|
118
|
+
"group": "Clippy"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"id": "clippy-unusual-byte-groupings",
|
|
122
|
+
"document": "rules/clippy-unusual-byte-groupings.json",
|
|
123
|
+
"title": "Clippy unusual_byte_groupings: Binary or hex literals that aren't grouped by four",
|
|
124
|
+
"group": "Clippy"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "clippy-zero-prefixed-literal",
|
|
128
|
+
"document": "rules/clippy-zero-prefixed-literal.json",
|
|
129
|
+
"title": "Clippy zero_prefixed_literal: Integer literals starting with `0`",
|
|
130
|
+
"group": "Clippy"
|
|
131
|
+
}
|
|
132
|
+
]
|
|
19
133
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-builtin-type-shadow",
|
|
4
|
+
"revision": 2,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Don't name a Rust generic type parameter after a primitive type such as u32 or bool; it shadows the real type inside the item.",
|
|
7
|
+
"scope": { "include": ["**/*"], "exclude": [] },
|
|
8
|
+
"clauses": [{
|
|
9
|
+
"id": "builtin-type-shadow",
|
|
10
|
+
"forbid": { "ast": { "language": "rust", "rule": { "kind": "type_identifier", "regex": "^(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize|f16|f32|f64|f128|bool|char|str)$", "inside": { "kind": "type_parameter", "stopBy": "end" } } } },
|
|
11
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::builtin_type_shadow", "clippy::all", "clippy::style", "warnings"] } }, "anchor": "witness.span", "code": "builtin_type_shadow", "message": "Rename this type parameter, e.g. T instead of u32, so it doesn't shadow the primitive type." }
|
|
12
|
+
}]
|
|
13
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-inconsistent-digit-grouping",
|
|
4
|
+
"revision": 2,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Group the digits of Rust decimal literals with underscores in equal-size groups, the same way in the integer part and the fraction.",
|
|
7
|
+
"scope": {"include": ["**/*"], "exclude": []},
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "inconsistent",
|
|
11
|
+
"forbid": { "ast": { "language": "rust", "rule": { "all": [
|
|
12
|
+
{"any": [{"kind": "integer_literal"}, {"kind": "float_literal"}]},
|
|
13
|
+
{ "all": [
|
|
14
|
+
{"not": {"inside": {"stopBy": "end", "kind": "macro_definition"}}},
|
|
15
|
+
{"not": {"regex": "^[0-9][0-9_]*_(?:8|16|32|64)$"}},
|
|
16
|
+
{"not": {"regex": "^0[xbo][0-9A-Fa-f_]*_(?:8|16|32|64)$"}},
|
|
17
|
+
{"not": {"regex": "^[0-9_.]*[eE][+-]?[0-9_]*_(?:32|64)$"}},
|
|
18
|
+
{"not": {"regex": "^0x[0-9A-Fa-f]{8}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{12}(?:_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)))?$"}},
|
|
19
|
+
{ "any": [
|
|
20
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"all": [{"not": {"regex": "^[0-9]+(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}}, {"not": {"regex": "^(?:[0-9]{1,1}(?:_[0-9]{1})+|[0-9]{1,2}(?:_[0-9]{2})+|[0-9]{1,3}(?:_[0-9]{3})+|[0-9]{1,4}(?:_[0-9]{4})+|[0-9]{1,5}(?:_[0-9]{5})+|[0-9]{1,6}(?:_[0-9]{6})+|[0-9]{1,7}(?:_[0-9]{7})+|[0-9]{1,8}(?:_[0-9]{8})+|[0-9]{1,9}(?:_[0-9]{9})+|[0-9]{1,10}(?:_[0-9]{10})+|[0-9]{1,11}(?:_[0-9]{11})+|[0-9]{1,12}(?:_[0-9]{12})+|[0-9]{1,13}(?:_[0-9]{13})+|[0-9]{1,14}(?:_[0-9]{14})+|[0-9]{1,15}(?:_[0-9]{15})+|[0-9]{1,16}(?:_[0-9]{16})+|[0-9]{1,17}(?:_[0-9]{17})+|[0-9]{1,18}(?:_[0-9]{18})+|[0-9]{1,19}(?:_[0-9]{19})+|[0-9]{1,20}(?:_[0-9]{20})+|[0-9]{1,21}(?:_[0-9]{21})+|[0-9]{1,22}(?:_[0-9]{22})+|[0-9]{1,23}(?:_[0-9]{23})+|[0-9]{1,24}(?:_[0-9]{24})+|[0-9]{1,25}(?:_[0-9]{25})+|[0-9]{1,26}(?:_[0-9]{26})+|[0-9]{1,27}(?:_[0-9]{27})+|[0-9]{1,28}(?:_[0-9]{28})+|[0-9]{1,29}(?:_[0-9]{29})+|[0-9]{1,30}(?:_[0-9]{30})+|[0-9]{1,31}(?:_[0-9]{31})+|[0-9]{1,32}(?:_[0-9]{32})+|[0-9]{1,33}(?:_[0-9]{33})+|[0-9]{1,34}(?:_[0-9]{34})+|[0-9]{1,35}(?:_[0-9]{35})+|[0-9]{1,36}(?:_[0-9]{36})+|[0-9]{1,37}(?:_[0-9]{37})+|[0-9]{1,38}(?:_[0-9]{38})+|[0-9]{1,39}(?:_[0-9]{39})+|[0-9]{1,40}(?:_[0-9]{40})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}}]}]},
|
|
21
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,5}|[0-9]{1,1}(?:_[0-9]{1})+|[0-9]{1,2}(?:_[0-9]{2})+|[0-9]{1,3}(?:_[0-9]{3})+|[0-9]{1,4}(?:_[0-9]{4})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"all": [{"regex": "^[^.]*\\..*$"}, {"not": {"regex": "^[0-9_]*\\.[0-9]*(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}}, {"not": {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+[0-9]{1,1}|(?:[0-9]{2}_)+[0-9]{1,2}|(?:[0-9]{3}_)+[0-9]{1,3}|(?:[0-9]{4}_)+[0-9]{1,4}|(?:[0-9]{5}_)+[0-9]{1,5}|(?:[0-9]{6}_)+[0-9]{1,6}|(?:[0-9]{7}_)+[0-9]{1,7}|(?:[0-9]{8}_)+[0-9]{1,8}|(?:[0-9]{9}_)+[0-9]{1,9}|(?:[0-9]{10}_)+[0-9]{1,10}|(?:[0-9]{11}_)+[0-9]{1,11}|(?:[0-9]{12}_)+[0-9]{1,12}|(?:[0-9]{13}_)+[0-9]{1,13}|(?:[0-9]{14}_)+[0-9]{1,14}|(?:[0-9]{15}_)+[0-9]{1,15}|(?:[0-9]{16}_)+[0-9]{1,16}|(?:[0-9]{17}_)+[0-9]{1,17}|(?:[0-9]{18}_)+[0-9]{1,18}|(?:[0-9]{19}_)+[0-9]{1,19}|(?:[0-9]{20}_)+[0-9]{1,20}|(?:[0-9]{21}_)+[0-9]{1,21}|(?:[0-9]{22}_)+[0-9]{1,22}|(?:[0-9]{23}_)+[0-9]{1,23}|(?:[0-9]{24}_)+[0-9]{1,24}|(?:[0-9]{25}_)+[0-9]{1,25}|(?:[0-9]{26}_)+[0-9]{1,26}|(?:[0-9]{27}_)+[0-9]{1,27}|(?:[0-9]{28}_)+[0-9]{1,28}|(?:[0-9]{29}_)+[0-9]{1,29}|(?:[0-9]{30}_)+[0-9]{1,30}|(?:[0-9]{31}_)+[0-9]{1,31}|(?:[0-9]{32}_)+[0-9]{1,32}|(?:[0-9]{33}_)+[0-9]{1,33}|(?:[0-9]{34}_)+[0-9]{1,34}|(?:[0-9]{35}_)+[0-9]{1,35}|(?:[0-9]{36}_)+[0-9]{1,36}|(?:[0-9]{37}_)+[0-9]{1,37}|(?:[0-9]{38}_)+[0-9]{1,38}|(?:[0-9]{39}_)+[0-9]{1,39}|(?:[0-9]{40}_)+[0-9]{1,40})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+|(?:[0-9]{2}_)+|(?:[0-9]{3}_)+|(?:[0-9]{4}_)+|(?:[0-9]{5}_)+|(?:[0-9]{6}_)+|(?:[0-9]{7}_)+|(?:[0-9]{8}_)+|(?:[0-9]{9}_)+|(?:[0-9]{10}_)+|(?:[0-9]{11}_)+|(?:[0-9]{12}_)+|(?:[0-9]{13}_)+|(?:[0-9]{14}_)+|(?:[0-9]{15}_)+|(?:[0-9]{16}_)+|(?:[0-9]{17}_)+|(?:[0-9]{18}_)+|(?:[0-9]{19}_)+|(?:[0-9]{20}_)+|(?:[0-9]{21}_)+|(?:[0-9]{22}_)+|(?:[0-9]{23}_)+|(?:[0-9]{24}_)+|(?:[0-9]{25}_)+|(?:[0-9]{26}_)+|(?:[0-9]{27}_)+|(?:[0-9]{28}_)+|(?:[0-9]{29}_)+|(?:[0-9]{30}_)+|(?:[0-9]{31}_)+|(?:[0-9]{32}_)+|(?:[0-9]{33}_)+|(?:[0-9]{34}_)+|(?:[0-9]{35}_)+|(?:[0-9]{36}_)+|(?:[0-9]{37}_)+|(?:[0-9]{38}_)+|(?:[0-9]{39}_)+|(?:[0-9]{40}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}}]}]},
|
|
22
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,1}(?:_[0-9]{1})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"regex": "^[0-9_]*\\.[0-9]{2,5}(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]},
|
|
23
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,2}(?:_[0-9]{2})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"regex": "^[0-9_]*\\.[0-9]{3,5}(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]},
|
|
24
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,3}(?:_[0-9]{3})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"regex": "^[0-9_]*\\.[0-9]{4,5}(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]},
|
|
25
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,4}(?:_[0-9]{4})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"regex": "^[0-9_]*\\.[0-9]{5,5}(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]},
|
|
26
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^[0-9]{2,5}(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+[0-9]{1,1})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]},
|
|
27
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^[0-9]{3,5}(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{2}_)+[0-9]{1,2})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{2}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]},
|
|
28
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^[0-9]{4,5}(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{3}_)+[0-9]{1,3})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{3}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]},
|
|
29
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^[0-9]{5,5}(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{4}_)+[0-9]{1,4})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{4}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]},
|
|
30
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,1}(?:_[0-9]{1})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{2}_)+[0-9]{1,2}|(?:[0-9]{3}_)+[0-9]{1,3}|(?:[0-9]{4}_)+[0-9]{1,4})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{2}_)+|(?:[0-9]{3}_)+|(?:[0-9]{4}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]},
|
|
31
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,2}(?:_[0-9]{2})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+[0-9]{1,1}|(?:[0-9]{3}_)+[0-9]{1,3}|(?:[0-9]{4}_)+[0-9]{1,4})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+|(?:[0-9]{3}_)+|(?:[0-9]{4}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]},
|
|
32
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,3}(?:_[0-9]{3})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+[0-9]{1,1}|(?:[0-9]{2}_)+[0-9]{1,2}|(?:[0-9]{4}_)+[0-9]{1,4})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+|(?:[0-9]{2}_)+|(?:[0-9]{4}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]},
|
|
33
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,4}(?:_[0-9]{4})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+[0-9]{1,1}|(?:[0-9]{2}_)+[0-9]{1,2}|(?:[0-9]{3}_)+[0-9]{1,3})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{1}_)+|(?:[0-9]{2}_)+|(?:[0-9]{3}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]}
|
|
34
|
+
] }
|
|
35
|
+
] }
|
|
36
|
+
] } } },
|
|
37
|
+
"violation": {"suppress": {"clippy": {"lints": ["clippy::inconsistent_digit_grouping", "clippy::all", "clippy::style", "warnings"]}}, "anchor": "witness.span", "code": "inconsistent_digit_grouping", "message": "Regroup this literal's digits with underscores into equal-size groups, e.g. 1_000_000 instead of 1_0000_00."}
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-int-plus-one",
|
|
4
|
+
"revision": 2,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Use a strict comparison in Rust instead of a non-strict one that adds or subtracts one; it states the bound directly.",
|
|
7
|
+
"scope": { "include": ["**/*"], "exclude": [] },
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "ge-adjusted",
|
|
11
|
+
"forbid": { "ast": { "language": "rust", "rule": { "all": [
|
|
12
|
+
{ "kind": "binary_expression" }, { "has": { "field": "operator", "regex": "^>=$" } },
|
|
13
|
+
{ "any": [
|
|
14
|
+
{ "has": { "field": "right", "kind": "binary_expression", "all": [ { "has": { "field": "operator", "regex": "^\\+$" } }, { "has": { "field": "right", "regex": "^1(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$" } } ] } },
|
|
15
|
+
{ "has": { "field": "right", "kind": "binary_expression", "all": [ { "has": { "field": "operator", "regex": "^\\+$" } }, { "has": { "field": "left", "regex": "^1(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$" } } ] } },
|
|
16
|
+
{ "has": { "field": "left", "kind": "binary_expression", "all": [ { "has": { "field": "operator", "regex": "^-$" } }, { "has": { "field": "right", "regex": "^1(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$" } } ] } },
|
|
17
|
+
{ "has": { "field": "left", "kind": "binary_expression", "all": [ { "has": { "field": "operator", "regex": "^\\+$" } }, { "has": { "field": "left", "regex": "^-1(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$" } } ] } }
|
|
18
|
+
] }
|
|
19
|
+
] } } },
|
|
20
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::int_plus_one", "clippy::all", "clippy::complexity", "warnings"] } }, "anchor": "witness.span", "code": "int_plus_one", "message": "Use > and drop the one here, e.g. x > y instead of x >= y + 1 or x - 1 >= y." }
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "le-adjusted",
|
|
24
|
+
"forbid": { "ast": { "language": "rust", "rule": { "all": [
|
|
25
|
+
{ "kind": "binary_expression" }, { "has": { "field": "operator", "regex": "^<=$" } },
|
|
26
|
+
{ "any": [
|
|
27
|
+
{ "has": { "field": "left", "kind": "binary_expression", "all": [ { "has": { "field": "operator", "regex": "^\\+$" } }, { "has": { "field": "right", "regex": "^1(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$" } } ] } },
|
|
28
|
+
{ "has": { "field": "left", "kind": "binary_expression", "all": [ { "has": { "field": "operator", "regex": "^\\+$" } }, { "has": { "field": "left", "regex": "^1(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$" } } ] } },
|
|
29
|
+
{ "has": { "field": "right", "kind": "binary_expression", "all": [ { "has": { "field": "operator", "regex": "^-$" } }, { "has": { "field": "right", "regex": "^1(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$" } } ] } },
|
|
30
|
+
{ "has": { "field": "right", "kind": "binary_expression", "all": [ { "has": { "field": "operator", "regex": "^\\+$" } }, { "has": { "field": "left", "regex": "^-1(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$" } } ] } }
|
|
31
|
+
] }
|
|
32
|
+
] } } },
|
|
33
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::int_plus_one", "clippy::all", "clippy::complexity", "warnings"] } }, "anchor": "witness.span", "code": "int_plus_one", "message": "Use < and drop the one here, e.g. x < y instead of x + 1 <= y or x <= y - 1." }
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-large-digit-groups",
|
|
4
|
+
"revision": 2,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Keep underscore-separated digit groups in Rust decimal literals to four digits or fewer; longer groups defeat the separators.",
|
|
7
|
+
"scope": {"include": ["**/*"], "exclude": []},
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "large",
|
|
11
|
+
"forbid": { "ast": { "language": "rust", "rule": { "all": [
|
|
12
|
+
{"any": [{"kind": "integer_literal"}, {"kind": "float_literal"}]},
|
|
13
|
+
{ "all": [
|
|
14
|
+
{"not": {"inside": {"stopBy": "end", "kind": "macro_definition"}}},
|
|
15
|
+
{"not": {"regex": "^[0-9][0-9_]*_(?:8|16|32|64)$"}},
|
|
16
|
+
{"not": {"regex": "^0[xbo][0-9A-Fa-f_]*_(?:8|16|32|64)$"}},
|
|
17
|
+
{"not": {"regex": "^[0-9_.]*[eE][+-]?[0-9_]*_(?:32|64)$"}},
|
|
18
|
+
{"not": {"regex": "^0x[0-9A-Fa-f]{8}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{12}(?:_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)))?$"}},
|
|
19
|
+
{ "any": [
|
|
20
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,5}(?:_[0-9]{5})+|[0-9]{1,6}(?:_[0-9]{6})+|[0-9]{1,7}(?:_[0-9]{7})+|[0-9]{1,8}(?:_[0-9]{8})+|[0-9]{1,9}(?:_[0-9]{9})+|[0-9]{1,10}(?:_[0-9]{10})+|[0-9]{1,11}(?:_[0-9]{11})+|[0-9]{1,12}(?:_[0-9]{12})+|[0-9]{1,13}(?:_[0-9]{13})+|[0-9]{1,14}(?:_[0-9]{14})+|[0-9]{1,15}(?:_[0-9]{15})+|[0-9]{1,16}(?:_[0-9]{16})+|[0-9]{1,17}(?:_[0-9]{17})+|[0-9]{1,18}(?:_[0-9]{18})+|[0-9]{1,19}(?:_[0-9]{19})+|[0-9]{1,20}(?:_[0-9]{20})+|[0-9]{1,21}(?:_[0-9]{21})+|[0-9]{1,22}(?:_[0-9]{22})+|[0-9]{1,23}(?:_[0-9]{23})+|[0-9]{1,24}(?:_[0-9]{24})+|[0-9]{1,25}(?:_[0-9]{25})+|[0-9]{1,26}(?:_[0-9]{26})+|[0-9]{1,27}(?:_[0-9]{27})+|[0-9]{1,28}(?:_[0-9]{28})+|[0-9]{1,29}(?:_[0-9]{29})+|[0-9]{1,30}(?:_[0-9]{30})+|[0-9]{1,31}(?:_[0-9]{31})+|[0-9]{1,32}(?:_[0-9]{32})+|[0-9]{1,33}(?:_[0-9]{33})+|[0-9]{1,34}(?:_[0-9]{34})+|[0-9]{1,35}(?:_[0-9]{35})+|[0-9]{1,36}(?:_[0-9]{36})+|[0-9]{1,37}(?:_[0-9]{37})+|[0-9]{1,38}(?:_[0-9]{38})+|[0-9]{1,39}(?:_[0-9]{39})+|[0-9]{1,40}(?:_[0-9]{40})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]},
|
|
21
|
+
{"all": [{"regex": "^(?:[1-9].*|0|0[^xbo].*)$"}, {"regex": "^(?:[0-9]{1,5}|[0-9]{1,1}(?:_[0-9]{1})+|[0-9]{1,2}(?:_[0-9]{2})+|[0-9]{1,3}(?:_[0-9]{3})+|[0-9]{1,4}(?:_[0-9]{4})+)(?:\\..*|_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[^.]*\\..*$"}, {"any": [{"regex": "^[0-9_]*\\.(?:(?:[0-9]{5}_)+[0-9]{1,5}|(?:[0-9]{6}_)+[0-9]{1,6}|(?:[0-9]{7}_)+[0-9]{1,7}|(?:[0-9]{8}_)+[0-9]{1,8}|(?:[0-9]{9}_)+[0-9]{1,9}|(?:[0-9]{10}_)+[0-9]{1,10}|(?:[0-9]{11}_)+[0-9]{1,11}|(?:[0-9]{12}_)+[0-9]{1,12}|(?:[0-9]{13}_)+[0-9]{1,13}|(?:[0-9]{14}_)+[0-9]{1,14}|(?:[0-9]{15}_)+[0-9]{1,15}|(?:[0-9]{16}_)+[0-9]{1,16}|(?:[0-9]{17}_)+[0-9]{1,17}|(?:[0-9]{18}_)+[0-9]{1,18}|(?:[0-9]{19}_)+[0-9]{1,19}|(?:[0-9]{20}_)+[0-9]{1,20}|(?:[0-9]{21}_)+[0-9]{1,21}|(?:[0-9]{22}_)+[0-9]{1,22}|(?:[0-9]{23}_)+[0-9]{1,23}|(?:[0-9]{24}_)+[0-9]{1,24}|(?:[0-9]{25}_)+[0-9]{1,25}|(?:[0-9]{26}_)+[0-9]{1,26}|(?:[0-9]{27}_)+[0-9]{1,27}|(?:[0-9]{28}_)+[0-9]{1,28}|(?:[0-9]{29}_)+[0-9]{1,29}|(?:[0-9]{30}_)+[0-9]{1,30}|(?:[0-9]{31}_)+[0-9]{1,31}|(?:[0-9]{32}_)+[0-9]{1,32}|(?:[0-9]{33}_)+[0-9]{1,33}|(?:[0-9]{34}_)+[0-9]{1,34}|(?:[0-9]{35}_)+[0-9]{1,35}|(?:[0-9]{36}_)+[0-9]{1,36}|(?:[0-9]{37}_)+[0-9]{1,37}|(?:[0-9]{38}_)+[0-9]{1,38}|(?:[0-9]{39}_)+[0-9]{1,39}|(?:[0-9]{40}_)+[0-9]{1,40})(?:_?[eE].*|_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}, {"regex": "^[0-9_]*\\.(?:(?:[0-9]{5}_)+|(?:[0-9]{6}_)+|(?:[0-9]{7}_)+|(?:[0-9]{8}_)+|(?:[0-9]{9}_)+|(?:[0-9]{10}_)+|(?:[0-9]{11}_)+|(?:[0-9]{12}_)+|(?:[0-9]{13}_)+|(?:[0-9]{14}_)+|(?:[0-9]{15}_)+|(?:[0-9]{16}_)+|(?:[0-9]{17}_)+|(?:[0-9]{18}_)+|(?:[0-9]{19}_)+|(?:[0-9]{20}_)+|(?:[0-9]{21}_)+|(?:[0-9]{22}_)+|(?:[0-9]{23}_)+|(?:[0-9]{24}_)+|(?:[0-9]{25}_)+|(?:[0-9]{26}_)+|(?:[0-9]{27}_)+|(?:[0-9]{28}_)+|(?:[0-9]{29}_)+|(?:[0-9]{30}_)+|(?:[0-9]{31}_)+|(?:[0-9]{32}_)+|(?:[0-9]{33}_)+|(?:[0-9]{34}_)+|(?:[0-9]{35}_)+|(?:[0-9]{36}_)+|(?:[0-9]{37}_)+|(?:[0-9]{38}_)+|(?:[0-9]{39}_)+|(?:[0-9]{40}_)+)(?:_[eE].*|_(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)|(?:f32|f64))|)$"}]}]}
|
|
22
|
+
] }
|
|
23
|
+
] }
|
|
24
|
+
] } } },
|
|
25
|
+
"violation": {"suppress": {"clippy": {"lints": ["clippy::large_digit_groups", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "large_digit_groups", "message": "Split this literal into digit groups of four or fewer, e.g. 1_000_000 instead of 1_000000."}
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-many-single-char-names",
|
|
4
|
+
"revision": 1,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Avoid more than four single-character variable names in scope at once in a Rust function, tests excluded; descriptive names are easier to follow.",
|
|
7
|
+
"scope": {"include": ["**/*"], "exclude": []},
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "many-single-char-names",
|
|
11
|
+
"forbid": { "ast": { "language": "rust",
|
|
12
|
+
"utils": {
|
|
13
|
+
"counted": {"kind": "identifier", "regex": "^[^\\p{Lu}\\d_]$", "any": [{"binds": {"form": "parameter", "site": {"kind": "parameter"}}}, {"binds": {"form": "assignment", "site": {"kind": "let_declaration"}}}, {"binds": {"form": "match", "site": {"kind": "match_arm"}}}]},
|
|
14
|
+
"scope-node": {"any": [{"kind": "block", "not": {"inside": {"field": "body", "kind": "function_item"}}}, {"kind": "match_arm"}]},
|
|
15
|
+
"stack-before": {"params": ["T"], "rule": {"any": [{"binds": {"form": "parameter", "site": {"kind": "parameter"}}}, {"inside": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "kind": "let_declaration", "precedes": {"stopBy": "end", "any": [{"all": [{"pattern": "$S"}, {"compare": {"left": "S", "op": "eq", "right": "T", "text": "node"}}]}, {"has": {"stopBy": "end", "pattern": "$S", "all": [{"compare": {"left": "S", "op": "eq", "right": "T", "text": "node"}}]}}]}}}, {"inside": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "kind": "match_pattern", "inside": {"kind": "match_arm", "has": {"field": "value", "any": [{"all": [{"pattern": "$S"}, {"compare": {"left": "S", "op": "eq", "right": "T", "text": "node"}}]}, {"has": {"stopBy": "end", "pattern": "$S", "all": [{"compare": {"left": "S", "op": "eq", "right": "T", "text": "node"}}]}}]}}}}]}},
|
|
16
|
+
"fresh": {"all": [{"pattern": "$Y"}, {"not": {"binds": {"redefines": {}}}}, {"any": [{"not": {"inside": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "scope-node"}}}, {"inside": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "scope-node", "pattern": "$Z", "not": {"inside": {"stopBy": {"kind": "function_item"}, "kind": "function_item", "has": {"stopBy": {"kind": "function_item"}, "matches": "counted", "pattern": "$Y", "all": [{"matches": {"stack-before": {"T": "$Z"}}}]}}}}}]}]}
|
|
17
|
+
},
|
|
18
|
+
"rule": { "all": [
|
|
19
|
+
{"kind": "function_item"},
|
|
20
|
+
{"has": {"field": "body", "kind": "block"}},
|
|
21
|
+
{"count": {"has": {"stopBy": {"kind": "function_item"}, "kind": "identifier", "regex": "^[^\\p{Lu}\\d_]$"}, "min": 5}},
|
|
22
|
+
{"not": {"inside": {"kind": "declaration_list", "inside": {"kind": "trait_item"}}}},
|
|
23
|
+
{"not": {"follows": {"stopBy": {"not": {"any": [{"kind": "attribute_item"}, {"kind": "line_comment"}, {"kind": "block_comment"}]}}, "kind": "attribute_item", "regex": "^#\\[\\s*test\\s*\\]$"}}},
|
|
24
|
+
{"has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "counted", "pattern": "$B"}},
|
|
25
|
+
{"any": [{"count": {"has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "counted", "all": [{"not": {"binds": {"redefines": {}}}}]}, "min": 5}}, {"has": {"stopBy": {"kind": "function_item"}, "matches": "scope-node", "pattern": "$SC", "all": [{"has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "kind": "identifier", "regex": "^[^\\p{Lu}\\d_]$", "matches": "counted"}}, {"inside": {"stopBy": {"kind": "function_item"}, "kind": "function_item", "has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "pattern": "$B", "all": [{"matches": {"stack-before": {"T": "$SC"}}}]}}}, {"any": [{"all": [{"count": {"has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "counted", "all": [{"matches": "fresh"}]}, "min": 1}}, {"inside": {"stopBy": {"kind": "function_item"}, "kind": "function_item", "count": {"has": {"stopBy": {"kind": "function_item"}, "matches": "counted", "all": [{"matches": {"stack-before": {"T": "$SC"}}}, {"matches": "fresh"}]}, "min": 4}}}]}, {"all": [{"count": {"has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "counted", "all": [{"matches": "fresh"}]}, "min": 2}}, {"inside": {"stopBy": {"kind": "function_item"}, "kind": "function_item", "count": {"has": {"stopBy": {"kind": "function_item"}, "matches": "counted", "all": [{"matches": {"stack-before": {"T": "$SC"}}}, {"matches": "fresh"}]}, "min": 3}}}]}, {"all": [{"count": {"has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "counted", "all": [{"matches": "fresh"}]}, "min": 3}}, {"inside": {"stopBy": {"kind": "function_item"}, "kind": "function_item", "count": {"has": {"stopBy": {"kind": "function_item"}, "matches": "counted", "all": [{"matches": {"stack-before": {"T": "$SC"}}}, {"matches": "fresh"}]}, "min": 2}}}]}, {"all": [{"count": {"has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "counted", "all": [{"matches": "fresh"}]}, "min": 4}}, {"inside": {"stopBy": {"kind": "function_item"}, "kind": "function_item", "count": {"has": {"stopBy": {"kind": "function_item"}, "matches": "counted", "all": [{"matches": {"stack-before": {"T": "$SC"}}}, {"matches": "fresh"}]}, "min": 1}}}]}, {"all": [{"count": {"has": {"stopBy": {"any": [{"matches": "scope-node"}, {"kind": "function_item"}]}, "matches": "counted", "all": [{"matches": "fresh"}]}, "min": 5}}]}]}]}}]}
|
|
26
|
+
] } } },
|
|
27
|
+
"violation": {"suppress": {"clippy": {"lints": ["clippy::many_single_char_names", "clippy::pedantic", "warnings"]}}, "anchor": "capture.B", "code": "many_single_char_names", "message": "Rename some of these single-letter variables to descriptive names; more than four are in scope here."}
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"format":"rerail.policy/v1","id":"clippy-mixed-case-hex-literals","revision":2,"mode":"steer","description":"Use one letter case for the digits of a Rust hexadecimal literal, all upper or all lower.","scope":{"include":["**/*"],"exclude":[]},"clauses":[{"id":"mixed-case-hex-literals","forbid":{"ast":{"language":"rust","rule":{"all":[{"kind":"integer_literal"},{"regex":"^0x[0-9A-Fa-f_]+(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$"},{"regex":"^0x[0-9A-Fa-f_]*[a-f]"},{"regex":"^0x[0-9A-Fa-f_]*[A-F]"}]}}},"violation":{"suppress":{"clippy":{"lints":["clippy::mixed_case_hex_literals","clippy::all","clippy::style","warnings"]}},"anchor":"witness.span","code":"mixed_case_hex_literals","message":"Use one letter case for this hex literal's digits, e.g. 0xABCD or 0xabcd, not 0xAbCd."}}]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-needless-arbitrary-self-type",
|
|
4
|
+
"revision": 1,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Write a Rust method receiver as self, &self or &mut self instead of spelling out its Self type.",
|
|
7
|
+
"scope": { "include": ["**/*"], "exclude": [] },
|
|
8
|
+
"clauses": [
|
|
9
|
+
{ "id": "self-explicit-self", "forbid": { "ast": { "language": "rust", "rule": { "kind": "parameter", "regex": "^(mut )?self: ?Self$" } } }, "violation": { "suppress": { "clippy": { "lints": ["clippy::needless_arbitrary_self_type", "clippy::all", "clippy::complexity", "warnings"] } }, "anchor": "witness.span", "code": "needless_arbitrary_self_type", "message": "Write this receiver as self or mut self instead of self: Self." } },
|
|
10
|
+
{ "id": "self-explicit-reference", "forbid": { "ast": { "language": "rust", "rule": { "kind": "parameter", "regex": "^self: &[^&]*Self$" } } }, "violation": { "suppress": { "clippy": { "lints": ["clippy::needless_arbitrary_self_type", "clippy::all", "clippy::complexity", "warnings"] } }, "anchor": "witness.span", "code": "needless_arbitrary_self_type", "message": "Write this receiver in short form, e.g. &self or &'a mut self instead of self: &'a mut Self." } }
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-needless-else",
|
|
4
|
+
"revision": 1,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Remove empty else blocks, with no code or comment, from Rust if statements.",
|
|
7
|
+
"scope": { "include": ["**/*"], "exclude": [] },
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "empty-else-block",
|
|
11
|
+
"forbid": { "ast": { "language": "rust", "rule": { "kind": "else_clause", "has": { "kind": "block", "regex": "^\\{\\s*\\}$" }, "not": { "regex": "(?s)/\\*|//" } } } },
|
|
12
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::needless_else", "clippy::all", "clippy::style", "warnings"] } }, "anchor": "witness.span", "code": "needless_else", "message": "Remove this empty else block." }
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-needless-raw-string-hashes",
|
|
4
|
+
"revision": 1,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Use no more hashes on a Rust raw string literal than its contents need to close it.",
|
|
7
|
+
"scope": {"include": ["**/*"], "exclude": []},
|
|
8
|
+
"clauses": [
|
|
9
|
+
{"id": "hashes-1", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r#\"(?s:.*)\"#$"}, {"regex": "^(?:b|c)?r#\"(?s:.*)[\\\\\"](?s:.*)\"#$"}, {"not": {"regex": "^(?:b|c)?r#\"(?s:.*)\"(?s:.*)\"#$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
10
|
+
{"id": "hashes-2", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r##\"(?s:.*)\"##$"}, {"regex": "^(?:b|c)?r##\"(?s:.*)[\\\\\"](?s:.*)\"##$"}, {"not": {"regex": "^(?:b|c)?r##\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"#(?s:.*)\"##$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
11
|
+
{"id": "hashes-3", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r###\"(?s:.*)\"###$"}, {"regex": "^(?:b|c)?r###\"(?s:.*)[\\\\\"](?s:.*)\"###$"}, {"not": {"regex": "^(?:b|c)?r###\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"##(?s:.*)\"###$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
12
|
+
{"id": "hashes-4", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r####\"(?s:.*)\"####$"}, {"regex": "^(?:b|c)?r####\"(?s:.*)[\\\\\"](?s:.*)\"####$"}, {"not": {"regex": "^(?:b|c)?r####\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"###(?s:.*)\"####$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
13
|
+
{"id": "hashes-5", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r#####\"(?s:.*)\"#####$"}, {"regex": "^(?:b|c)?r#####\"(?s:.*)[\\\\\"](?s:.*)\"#####$"}, {"not": {"regex": "^(?:b|c)?r#####\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"####(?s:.*)\"#####$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
14
|
+
{"id": "hashes-6", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r######\"(?s:.*)\"######$"}, {"regex": "^(?:b|c)?r######\"(?s:.*)[\\\\\"](?s:.*)\"######$"}, {"not": {"regex": "^(?:b|c)?r######\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"#####(?s:.*)\"######$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
15
|
+
{"id": "hashes-7", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r#######\"(?s:.*)\"#######$"}, {"regex": "^(?:b|c)?r#######\"(?s:.*)[\\\\\"](?s:.*)\"#######$"}, {"not": {"regex": "^(?:b|c)?r#######\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"######(?s:.*)\"#######$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
16
|
+
{"id": "hashes-8", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r########\"(?s:.*)\"########$"}, {"regex": "^(?:b|c)?r########\"(?s:.*)[\\\\\"](?s:.*)\"########$"}, {"not": {"regex": "^(?:b|c)?r########\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"#######(?s:.*)\"########$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
17
|
+
{"id": "hashes-9", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r#########\"(?s:.*)\"#########$"}, {"regex": "^(?:b|c)?r#########\"(?s:.*)[\\\\\"](?s:.*)\"#########$"}, {"not": {"regex": "^(?:b|c)?r#########\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"########(?s:.*)\"#########$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}},
|
|
18
|
+
{"id": "hashes-10", "forbid": {"ast": {"language": "rust", "rule": {"all": [{"kind": "raw_string_literal"}, {"regex": "^(?:b|c)?r##########\"(?s:.*)\"##########$"}, {"regex": "^(?:b|c)?r##########\"(?s:.*)[\\\\\"](?s:.*)\"##########$"}, {"not": {"regex": "^(?:b|c)?r##########\"(?:[^\"]|\"#*(?:\"|[^\"#]))*\"#########(?s:.*)\"##########$"}}]}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::needless_raw_string_hashes", "clippy::pedantic", "warnings"]}}, "anchor": "witness.span", "code": "needless_raw_string_hashes", "message": "Remove the extra # marks from this raw string, keeping only as many as its contents need to close it."}}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-octal-escapes",
|
|
4
|
+
"revision": 1,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Avoid a null escape followed by digits in Rust string literals; Rust has no octal escapes, so it yields a NUL then digits, not the intended character.",
|
|
7
|
+
"scope": { "include": ["**/*"], "exclude": [] },
|
|
8
|
+
"clauses": [{
|
|
9
|
+
"id": "octal-escape",
|
|
10
|
+
"forbid": { "ast": { "language": "rust", "rule": {
|
|
11
|
+
"kind": "string_literal",
|
|
12
|
+
"regex": "(?s)(?:^|[^\\\\]|\\\\\\\\)(?P<O>\\\\0[0-7]{1,2})"
|
|
13
|
+
} } },
|
|
14
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::octal_escapes", "clippy::all", "clippy::suspicious", "warnings"] } }, "anchor": "capture.O", "code": "octal_escapes", "message": "Replace this \\0 escape with the intended character, e.g. \\x1b for \\033, or \\x00 then the digits if NUL was meant." }
|
|
15
|
+
}, {
|
|
16
|
+
"id": "octal-escape-after-first",
|
|
17
|
+
"forbid": { "ast": { "language": "rust", "rule": {
|
|
18
|
+
"kind": "string_literal",
|
|
19
|
+
"regex": "(?s).*?(?:^|[^\\\\]|\\\\\\\\)\\\\0[0-7]{1,2}.*?(?P<O>\\\\0[0-7]{1,2})"
|
|
20
|
+
} } },
|
|
21
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::octal_escapes", "clippy::all", "clippy::suspicious", "warnings"] } }, "anchor": "capture.O", "code": "octal_escapes", "message": "Replace this \\0 escape with the intended character, e.g. \\x1b for \\033, or \\x00 then the digits if NUL was meant." }
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-partial-pub-fields",
|
|
4
|
+
"revision": 2,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Make a Rust struct's fields either all pub or all non-pub; mixing them blurs what the type exposes.",
|
|
7
|
+
"scope": { "include": ["**/*"], "exclude": [] },
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "shared",
|
|
11
|
+
"define": { "language": "rust", "utils": {
|
|
12
|
+
"pub-field": { "has": { "kind": "visibility_modifier", "regex": "^pub$" } },
|
|
13
|
+
"later-field": { "kind": "field_declaration", "inside": { "kind": "field_declaration_list", "inside": { "kind": "struct_item" } }, "follows": { "stopBy": "end", "kind": "field_declaration" } },
|
|
14
|
+
"first-pub-after-private": { "matches": "later-field", "all": [{ "matches": "pub-field" }, { "not": { "follows": { "stopBy": "end", "kind": "field_declaration", "matches": "pub-field" } } }] },
|
|
15
|
+
"first-private-after-pub": { "matches": "later-field", "all": [{ "not": { "matches": "pub-field" } }, { "not": { "follows": { "stopBy": "end", "kind": "field_declaration", "not": { "matches": "pub-field" } } } }] },
|
|
16
|
+
"skipped": { "any": [{ "kind": "attribute_item" }, { "kind": "line_comment" }, { "kind": "block_comment" }] },
|
|
17
|
+
"tuple-field": {
|
|
18
|
+
"inside": { "kind": "ordered_field_declaration_list", "inside": { "kind": "struct_item" } },
|
|
19
|
+
"follows": { "stopBy": { "not": { "any": [{ "matches": "skipped" }, { "kind": "visibility_modifier" }] } }, "regex": "^[(,]$" },
|
|
20
|
+
"not": { "any": [{ "matches": "skipped" }, { "kind": "visibility_modifier" }, { "regex": "^[(),]$" }] }
|
|
21
|
+
},
|
|
22
|
+
"tuple-vis": { "follows": { "stopBy": { "not": { "matches": "skipped" } }, "kind": "visibility_modifier" } },
|
|
23
|
+
"tuple-pub": { "follows": { "stopBy": { "not": { "matches": "skipped" } }, "kind": "visibility_modifier", "regex": "^pub$" } },
|
|
24
|
+
"tuple-first-private-after-pub": { "all": [
|
|
25
|
+
{ "matches": "tuple-field" },
|
|
26
|
+
{ "not": { "matches": "tuple-pub" } },
|
|
27
|
+
{ "follows": { "stopBy": "end", "regex": "^,$" } },
|
|
28
|
+
{ "not": { "follows": { "stopBy": "end", "matches": "tuple-field", "not": { "matches": "tuple-pub" } } } }
|
|
29
|
+
] }
|
|
30
|
+
} }
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "field-visibility",
|
|
34
|
+
"forbid": { "ast": { "language": "rust", "rule": { "kind": "visibility_modifier", "any": [
|
|
35
|
+
{ "inside": { "stopBy": "neighbor", "any": [{ "matches": "first-pub-after-private" }, { "matches": "first-private-after-pub" }] } },
|
|
36
|
+
{ "regex": "^pub$", "inside": { "kind": "ordered_field_declaration_list", "inside": { "kind": "struct_item" } }, "follows": { "stopBy": "end", "regex": "^,$" }, "not": { "follows": { "stopBy": "end", "kind": "visibility_modifier", "regex": "^pub$" } } },
|
|
37
|
+
{ "precedes": { "stopBy": { "not": { "matches": "skipped" } }, "matches": "tuple-first-private-after-pub" } }
|
|
38
|
+
] } } },
|
|
39
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::partial_pub_fields", "clippy::restriction", "warnings"] } }, "anchor": "witness.span", "code": "partial_pub_fields", "message": "Match this field's visibility to the struct's other fields: make all of them pub or none of them." }
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "inherited-visibility-after-pub",
|
|
43
|
+
"forbid": { "ast": { "language": "rust", "rule": { "any": [
|
|
44
|
+
{ "matches": "first-private-after-pub", "not": { "has": { "kind": "visibility_modifier" } } },
|
|
45
|
+
{ "matches": "tuple-first-private-after-pub", "not": { "matches": "tuple-vis" } }
|
|
46
|
+
] } } },
|
|
47
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::partial_pub_fields", "clippy::restriction", "warnings"] } }, "anchor": "witness.start", "code": "partial_pub_fields", "message": "Match this field's visibility to the struct's other fields: make all of them pub or none of them." }
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-precedence-bits",
|
|
4
|
+
"revision": 4,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Parenthesize shifts used as operands of a bitwise AND, OR or XOR in Rust; the precedence is easy to misread.",
|
|
7
|
+
"scope": {
|
|
8
|
+
"include": [
|
|
9
|
+
"**/*"
|
|
10
|
+
],
|
|
11
|
+
"exclude": []
|
|
12
|
+
},
|
|
13
|
+
"clauses": [
|
|
14
|
+
{
|
|
15
|
+
"id": "bitwise-with-shift",
|
|
16
|
+
"forbid": {
|
|
17
|
+
"ast": {
|
|
18
|
+
"language": "rust",
|
|
19
|
+
"rule": {
|
|
20
|
+
"matches": "lint"
|
|
21
|
+
},
|
|
22
|
+
"utils": {
|
|
23
|
+
"lint": {
|
|
24
|
+
"all": [
|
|
25
|
+
{
|
|
26
|
+
"kind": "binary_expression"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"has": {
|
|
30
|
+
"field": "operator",
|
|
31
|
+
"regex": "^[&^|]$"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"any": [
|
|
36
|
+
{
|
|
37
|
+
"has": {
|
|
38
|
+
"field": "left",
|
|
39
|
+
"kind": "binary_expression",
|
|
40
|
+
"has": {
|
|
41
|
+
"field": "operator",
|
|
42
|
+
"regex": "^(?:<<|>>)$"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"has": {
|
|
48
|
+
"field": "right",
|
|
49
|
+
"kind": "binary_expression",
|
|
50
|
+
"has": {
|
|
51
|
+
"field": "operator",
|
|
52
|
+
"regex": "^(?:<<|>>)$"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"not": {
|
|
60
|
+
"any": [
|
|
61
|
+
{
|
|
62
|
+
"has": {
|
|
63
|
+
"field": "left",
|
|
64
|
+
"kind": "binary_expression",
|
|
65
|
+
"has": {
|
|
66
|
+
"field": "operator",
|
|
67
|
+
"regex": "^[-+*/%]$"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"has": {
|
|
73
|
+
"field": "right",
|
|
74
|
+
"kind": "binary_expression",
|
|
75
|
+
"has": {
|
|
76
|
+
"field": "operator",
|
|
77
|
+
"regex": "^[-+*/%]$"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"violation": {
|
|
90
|
+
"suppress": {
|
|
91
|
+
"clippy": {
|
|
92
|
+
"lints": [
|
|
93
|
+
"clippy::precedence_bits",
|
|
94
|
+
"clippy::restriction",
|
|
95
|
+
"warnings"
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"anchor": "witness.span",
|
|
100
|
+
"code": "precedence_bits",
|
|
101
|
+
"message": "Add parentheses around the shift in this bitwise expression, e.g. (a << 4) | b."
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-precedence",
|
|
4
|
+
"revision": 3,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Parenthesize arithmetic used as an operand of a shift or bitwise operator in Rust; the precedence is easy to misread.",
|
|
7
|
+
"scope": { "include": ["**/*"], "exclude": [] },
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "shift-with-arithmetic",
|
|
11
|
+
"forbid": { "ast": { "language": "rust", "rule": { "kind": "binary_expression", "has": { "field": "operator", "regex": "^(?:<<|>>)$" }, "any": [ { "has": { "field": "left", "kind": "binary_expression", "has": { "field": "operator", "regex": "^[-+*/%]$" } } }, { "has": { "field": "right", "kind": "binary_expression", "has": { "field": "operator", "regex": "^[-+*/%]$" } } } ] } } },
|
|
12
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::precedence", "clippy::all", "clippy::complexity", "warnings"] } }, "anchor": "witness.span", "code": "precedence", "message": "Add parentheses around the arithmetic in this shift, e.g. (a + b) << c, to make the order explicit." }
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "bitwise-with-arithmetic",
|
|
16
|
+
"forbid": { "ast": { "language": "rust", "rule": { "kind": "binary_expression", "has": { "field": "operator", "regex": "^[&^|]$" }, "any": [ { "has": { "field": "left", "kind": "binary_expression", "has": { "field": "operator", "regex": "^[-+*/%]$" } } }, { "has": { "field": "right", "kind": "binary_expression", "has": { "field": "operator", "regex": "^[-+*/%]$" } } } ] } } },
|
|
17
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::precedence", "clippy::all", "clippy::complexity", "warnings"] } }, "anchor": "witness.span", "code": "precedence", "message": "Add parentheses around the arithmetic in this bitwise expression, e.g. (a + b) & mask, to make the order explicit." }
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": "closure-block-call",
|
|
21
|
+
"forbid": { "ast": { "language": "rust", "rule": { "kind": "call_expression", "has": { "field": "function", "kind": "field_expression", "has": { "field": "value", "kind": "closure_expression" } } } } },
|
|
22
|
+
"violation": { "suppress": { "clippy": { "lints": ["clippy::precedence", "clippy::all", "clippy::complexity", "warnings"] } }, "anchor": "witness.span", "code": "precedence", "message": "Wrap this closure in parentheses so it's clear the method call applies to the closure, not its body." }
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-redundant-at-rest-pattern",
|
|
4
|
+
"revision": 1,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Bind a whole Rust slice directly instead of through a slice pattern holding only a rest binding.",
|
|
7
|
+
"scope": { "include": ["**/*"], "exclude": [] },
|
|
8
|
+
"clauses": [
|
|
9
|
+
{ "id": "redundant-slice-rest-binding", "forbid": { "ast": { "language": "rust", "rule": { "kind": "slice_pattern", "regex": "(?s)^\\[\\s*(?:(?:ref\\s+mut|ref|mut)\\s+)?[A-Za-z_][A-Za-z0-9_]*\\s*@\\s*\\.\\.\\s*\\]$" } } }, "violation": { "suppress": { "clippy": { "lints": ["clippy::redundant_at_rest_pattern", "clippy::all", "clippy::complexity", "warnings"] } }, "anchor": "witness.span", "code": "redundant_at_rest_pattern", "message": "Bind the whole slice directly, e.g. rest instead of [rest @ ..]." } }
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-single-component-path-imports",
|
|
4
|
+
"revision": 1,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Remove private imports of a bare crate name in Rust 2018 and later; the crate is already in scope without them.",
|
|
7
|
+
"scope": {"include": ["**/*"], "exclude": []},
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "single-component-import",
|
|
11
|
+
"forbid": { "ast": { "language": "rust",
|
|
12
|
+
"utils": {
|
|
13
|
+
"module-item": {"inside": {"any": [{"kind": "source_file"}, {"kind": "declaration_list", "inside": {"kind": "mod_item"}}]}},
|
|
14
|
+
"not-pub": {"not": {"has": {"kind": "visibility_modifier", "regex": "^pub$"}}},
|
|
15
|
+
"starts-with-n": {"any": [{"kind": "identifier", "pattern": "$N"}, {"has": {"field": "path", "matches": "starts-with-n"}}, {"kind": "use_wildcard", "has": {"matches": "starts-with-n"}}]},
|
|
16
|
+
"self-n": {"kind": "scoped_identifier", "has": {"field": "path", "kind": "self"}, "all": [{"has": {"field": "name", "pattern": "$N"}}]},
|
|
17
|
+
"reused-with-self": {"any": [{"follows": {"stopBy": "end", "kind": "use_declaration", "matches": "not-pub", "has": {"stopBy": "end", "any": [{"matches": "self-n"}, {"kind": "scoped_use_list", "has": {"field": "path", "kind": "self"}, "all": [{"has": {"field": "list", "has": {"matches": "starts-with-n"}}}]}]}}}, {"precedes": {"stopBy": "end", "kind": "use_declaration", "matches": "not-pub", "has": {"stopBy": "end", "any": [{"matches": "self-n"}, {"kind": "scoped_use_list", "has": {"field": "path", "kind": "self"}, "all": [{"has": {"field": "list", "has": {"matches": "starts-with-n"}}}]}]}}}, {"inside": {"any": [{"kind": "source_file"}, {"kind": "declaration_list"}], "has": {"stopBy": "end", "matches": "self-n", "not": {"inside": {"stopBy": "end", "kind": "use_declaration"}}}}}, {"follows": {"stopBy": "end", "kind": "macro_definition", "has": {"field": "name", "pattern": "$N"}}}]}
|
|
18
|
+
},
|
|
19
|
+
"rule": {"all": [{"kind": "use_declaration"}, {"has": {"field": "argument", "kind": "identifier", "pattern": "$N"}}, {"matches": "module-item"}, {"matches": "not-pub"}, {"not": {"matches": "reused-with-self"}}]} } },
|
|
20
|
+
"violation": {"suppress": {"clippy": {"lints": ["clippy::single_component_path_imports", "clippy::all", "clippy::style", "warnings"]}}, "anchor": "witness.span", "code": "single_component_path_imports", "message": "Remove this use of a bare crate name; the crate is already in scope."}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "nested-single-component-import",
|
|
24
|
+
"forbid": { "ast": { "language": "rust",
|
|
25
|
+
"utils": {
|
|
26
|
+
"module-item": {"inside": {"any": [{"kind": "source_file"}, {"kind": "declaration_list", "inside": {"kind": "mod_item"}}]}},
|
|
27
|
+
"not-pub": {"not": {"has": {"kind": "visibility_modifier", "regex": "^pub$"}}},
|
|
28
|
+
"starts-with-n": {"any": [{"kind": "identifier", "pattern": "$N"}, {"has": {"field": "path", "matches": "starts-with-n"}}, {"kind": "use_wildcard", "has": {"matches": "starts-with-n"}}]},
|
|
29
|
+
"self-n": {"kind": "scoped_identifier", "has": {"field": "path", "kind": "self"}, "all": [{"has": {"field": "name", "pattern": "$N"}}]},
|
|
30
|
+
"reused-with-self": {"any": [{"follows": {"stopBy": "end", "kind": "use_declaration", "matches": "not-pub", "has": {"stopBy": "end", "any": [{"matches": "self-n"}, {"kind": "scoped_use_list", "has": {"field": "path", "kind": "self"}, "all": [{"has": {"field": "list", "has": {"matches": "starts-with-n"}}}]}]}}}, {"precedes": {"stopBy": "end", "kind": "use_declaration", "matches": "not-pub", "has": {"stopBy": "end", "any": [{"matches": "self-n"}, {"kind": "scoped_use_list", "has": {"field": "path", "kind": "self"}, "all": [{"has": {"field": "list", "has": {"matches": "starts-with-n"}}}]}]}}}, {"inside": {"any": [{"kind": "source_file"}, {"kind": "declaration_list"}], "has": {"stopBy": "end", "matches": "self-n", "not": {"inside": {"stopBy": "end", "kind": "use_declaration"}}}}}, {"follows": {"stopBy": "end", "kind": "macro_definition", "has": {"field": "name", "pattern": "$N"}}}]}
|
|
31
|
+
},
|
|
32
|
+
"rule": {"all": [{"kind": "identifier", "pattern": "$N"}, {"inside": {"kind": "use_list", "inside": {"field": "argument", "kind": "use_declaration", "matches": "module-item", "all": [{"matches": "not-pub"}, {"not": {"matches": "reused-with-self"}}]}}}]} } },
|
|
33
|
+
"violation": {"suppress": {"clippy": {"lints": ["clippy::single_component_path_imports", "clippy::all", "clippy::style", "warnings"]}}, "anchor": "witness.span", "code": "single_component_path_imports", "message": "Remove this bare crate name from the use list; the crate is already in scope."}
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-unneeded-wildcard-pattern",
|
|
4
|
+
"revision": 2,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Remove wildcard patterns next to a rest pattern in Rust; the rest pattern already ignores those elements.",
|
|
7
|
+
"scope": {
|
|
8
|
+
"include": [
|
|
9
|
+
"**/*"
|
|
10
|
+
],
|
|
11
|
+
"exclude": []
|
|
12
|
+
},
|
|
13
|
+
"clauses": [
|
|
14
|
+
{"id": "wildcards-before-rest", "forbid": {"ast": {"language": "rust", "rule": {"any": [{"kind": "tuple_pattern"}, {"kind": "tuple_struct_pattern"}], "regex": "(?s)^[^(]*\\((?:(?:[^()\\[\\]{}\"',]|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)'|[(\\[{](?:[^()\\[\\]{}\"']|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)'|[(\\[{](?:[^()\\[\\]{}\"']|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)')*[)\\]}])*[)\\]}])*,)*?\\s*(?P<W>(?:_\\s*,\\s*)+)\\.\\.\\s*[,)]"}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::unneeded_wildcard_pattern", "clippy::all", "clippy::complexity", "warnings"]}}, "anchor": "capture.W", "code": "unneeded_wildcard_pattern", "message": "Remove the _ wildcards before this ..; the rest pattern already skips them."}},
|
|
15
|
+
{"id": "wildcards-after-rest", "forbid": {"ast": {"language": "rust", "rule": {"any": [{"kind": "tuple_pattern"}, {"kind": "tuple_struct_pattern"}], "regex": "(?s)^[^(]*\\((?:(?:[^()\\[\\]{}\"',]|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)'|[(\\[{](?:[^()\\[\\]{}\"']|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)'|[(\\[{](?:[^()\\[\\]{}\"']|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)')*[)\\]}])*[)\\]}])*,)*?\\s*\\.\\.(?P<W>(?:\\s*,\\s*_)+)\\s*[,)]"}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::unneeded_wildcard_pattern", "clippy::all", "clippy::complexity", "warnings"]}}, "anchor": "capture.W", "code": "unneeded_wildcard_pattern", "message": "Remove the _ wildcards after this ..; the rest pattern already skips them."}},
|
|
16
|
+
{"id": "struct-wildcard-fields-before-rest", "forbid": {"ast": {"language": "rust", "rule": {"kind": "struct_pattern", "regex": "(?s)^[^{]*\\{(?:(?:[^()\\[\\]{}\"',]|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)'|[(\\[{](?:[^()\\[\\]{}\"']|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)'|[(\\[{](?:[^()\\[\\]{}\"']|\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)')*[)\\]}])*[)\\]}])*,)*?\\s*(?P<W>(?:[\\w#]+\\s*:\\s*_\\s*,\\s*)+)\\.\\.\\s*\\}"}}}, "violation": {"suppress": {"clippy": {"lints": ["clippy::unneeded_wildcard_pattern", "clippy::all", "clippy::complexity", "warnings"]}}, "anchor": "capture.W", "code": "unneeded_wildcard_pattern", "message": "Remove the field: _ entries before this ..; the rest pattern already skips those fields."}}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "rerail.policy/v1",
|
|
3
|
+
"id": "clippy-unusual-byte-groupings",
|
|
4
|
+
"revision": 2,
|
|
5
|
+
"mode": "steer",
|
|
6
|
+
"description": "Split Rust binary, octal and hexadecimal literals into equal-size digit groups; uneven groups hide the bit layout.",
|
|
7
|
+
"scope": {"include": ["**/*"], "exclude": []},
|
|
8
|
+
"clauses": [
|
|
9
|
+
{
|
|
10
|
+
"id": "unusual",
|
|
11
|
+
"forbid": { "ast": { "language": "rust", "rule": { "all": [
|
|
12
|
+
{"any": [{"kind": "integer_literal"}, {"kind": "float_literal"}]},
|
|
13
|
+
{ "all": [
|
|
14
|
+
{"not": {"inside": {"stopBy": "end", "kind": "macro_definition"}}},
|
|
15
|
+
{"not": {"regex": "^[0-9][0-9_]*_(?:8|16|32|64)$"}},
|
|
16
|
+
{"not": {"regex": "^0[xbo][0-9A-Fa-f_]*_(?:8|16|32|64)$"}},
|
|
17
|
+
{"not": {"regex": "^[0-9_.]*[eE][+-]?[0-9_]*_(?:32|64)$"}},
|
|
18
|
+
{"not": {"regex": "^0x[0-9A-Fa-f]{8}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{12}(?:_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)))?$"}},
|
|
19
|
+
{ "any": [
|
|
20
|
+
{"all": [{"regex": "^0[xbo].*$"}, {"not": {"regex": "^0[xbo][0-9A-Fa-f]+(?:_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)))?$"}}, {"not": {"regex": "^0[xbo](?:[0-9A-Fa-f]{0,1}(?:_[0-9A-Fa-f]{1})+|[0-9A-Fa-f]{0,2}(?:_[0-9A-Fa-f]{2})+|[0-9A-Fa-f]{0,3}(?:_[0-9A-Fa-f]{3})+|[0-9A-Fa-f]{0,4}(?:_[0-9A-Fa-f]{4})+|[0-9A-Fa-f]{0,5}(?:_[0-9A-Fa-f]{5})+|[0-9A-Fa-f]{0,6}(?:_[0-9A-Fa-f]{6})+|[0-9A-Fa-f]{0,7}(?:_[0-9A-Fa-f]{7})+|[0-9A-Fa-f]{0,8}(?:_[0-9A-Fa-f]{8})+|[0-9A-Fa-f]{0,9}(?:_[0-9A-Fa-f]{9})+|[0-9A-Fa-f]{0,10}(?:_[0-9A-Fa-f]{10})+|[0-9A-Fa-f]{0,11}(?:_[0-9A-Fa-f]{11})+|[0-9A-Fa-f]{0,12}(?:_[0-9A-Fa-f]{12})+|[0-9A-Fa-f]{0,13}(?:_[0-9A-Fa-f]{13})+|[0-9A-Fa-f]{0,14}(?:_[0-9A-Fa-f]{14})+|[0-9A-Fa-f]{0,15}(?:_[0-9A-Fa-f]{15})+|[0-9A-Fa-f]{0,16}(?:_[0-9A-Fa-f]{16})+|[0-9A-Fa-f]{0,17}(?:_[0-9A-Fa-f]{17})+|[0-9A-Fa-f]{0,18}(?:_[0-9A-Fa-f]{18})+|[0-9A-Fa-f]{0,19}(?:_[0-9A-Fa-f]{19})+|[0-9A-Fa-f]{0,20}(?:_[0-9A-Fa-f]{20})+|[0-9A-Fa-f]{0,21}(?:_[0-9A-Fa-f]{21})+|[0-9A-Fa-f]{0,22}(?:_[0-9A-Fa-f]{22})+|[0-9A-Fa-f]{0,23}(?:_[0-9A-Fa-f]{23})+|[0-9A-Fa-f]{0,24}(?:_[0-9A-Fa-f]{24})+|[0-9A-Fa-f]{0,25}(?:_[0-9A-Fa-f]{25})+|[0-9A-Fa-f]{0,26}(?:_[0-9A-Fa-f]{26})+|[0-9A-Fa-f]{0,27}(?:_[0-9A-Fa-f]{27})+|[0-9A-Fa-f]{0,28}(?:_[0-9A-Fa-f]{28})+|[0-9A-Fa-f]{0,29}(?:_[0-9A-Fa-f]{29})+|[0-9A-Fa-f]{0,30}(?:_[0-9A-Fa-f]{30})+|[0-9A-Fa-f]{0,31}(?:_[0-9A-Fa-f]{31})+|[0-9A-Fa-f]{0,32}(?:_[0-9A-Fa-f]{32})+|[0-9A-Fa-f]{0,33}(?:_[0-9A-Fa-f]{33})+|[0-9A-Fa-f]{0,34}(?:_[0-9A-Fa-f]{34})+|[0-9A-Fa-f]{0,35}(?:_[0-9A-Fa-f]{35})+|[0-9A-Fa-f]{0,36}(?:_[0-9A-Fa-f]{36})+|[0-9A-Fa-f]{0,37}(?:_[0-9A-Fa-f]{37})+|[0-9A-Fa-f]{0,38}(?:_[0-9A-Fa-f]{38})+|[0-9A-Fa-f]{0,39}(?:_[0-9A-Fa-f]{39})+|[0-9A-Fa-f]{0,40}(?:_[0-9A-Fa-f]{40})+)(?:_?(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize)))?$"}}]}
|
|
21
|
+
] }
|
|
22
|
+
] }
|
|
23
|
+
] } } },
|
|
24
|
+
"violation": {"suppress": {"clippy": {"lints": ["clippy::unusual_byte_groupings", "clippy::all", "clippy::style", "warnings"]}}, "anchor": "witness.span", "code": "unusual_byte_groupings", "message": "Regroup this literal's digits into equal-size groups, e.g. 0xFFFF_FFFF or 0b1010_1010."}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"format":"rerail.policy/v1","id":"clippy-zero-prefixed-literal","revision":2,"mode":"steer","description":"Avoid leading zeros on Rust decimal literals; Rust doesn't read them as octal, so use an explicit octal prefix or drop the zero.","scope":{"include":["**/*"],"exclude":[]},"clauses":[{"id":"zero-prefixed-literal","forbid":{"ast":{"language":"rust","rule":{"kind":"integer_literal","regex":"^0(?:[0-9]|_[0-9])[0-9_]*(?:(?:i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize))?$"}}},"violation":{"suppress":{"clippy":{"lints":["clippy::zero_prefixed_literal","clippy::all","clippy::complexity","warnings"]}},"anchor":"witness.span","code":"zero_prefixed_literal","message":"Drop the leading zero from this literal, or use the 0o prefix if you meant octal."}}]}
|