Skip to content

Commit 244d7ea

Browse files
committed
Verify that versions in the changelog match the lint definitions
1 parent 604b7b0 commit 244d7ea

File tree

8 files changed

+118
-29
lines changed

8 files changed

+118
-29
lines changed

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1243,8 +1243,6 @@ Released 2023-03-09
12431243

12441244
* [`permissions_set_readonly_false`]
12451245
[#10063](https://github.com/rust-lang/rust-clippy/pull/10063)
1246-
* [`almost_complete_range`]
1247-
[#10043](https://github.com/rust-lang/rust-clippy/pull/10043)
12481246
* [`size_of_ref`]
12491247
[#10098](https://github.com/rust-lang/rust-clippy/pull/10098)
12501248
* [`semicolon_outside_block`]
@@ -1264,6 +1262,8 @@ Released 2023-03-09
12641262
[#10115](https://github.com/rust-lang/rust-clippy/pull/10115)
12651263
* Renamed `derive_hash_xor_eq` to [`derived_hash_with_manual_eq`]
12661264
[#10184](https://github.com/rust-lang/rust-clippy/pull/10184)
1265+
* Renamed `almost_complete_letter_range` to [`almost_complete_range`] and extended it to check digits
1266+
[#10043](https://github.com/rust-lang/rust-clippy/pull/10043)
12671267

12681268
### Enhancements
12691269

book/src/development/infrastructure/changelog_update.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,14 @@ that label in the changelog. If you can, remove the `beta-accepted` labels
112112
### 4. Update `clippy::version` attributes
113113

114114
Next, make sure to check that the `#[clippy::version]` attributes for the added
115-
lints contain the correct version.
116-
In order to find lints that need a version update, go through the lints in the
117-
"New Lints" section and run the following command for each lint name:
115+
lints contain the correct version:
118116

119117
```
120-
grep -rB1 "pub $LINT_NAME" .
118+
cargo test --test lint-definitions
121119
```
122120

123-
The version shown should match the version of the release the changelog is
124-
written for. If not, update the version to the changelog version.
121+
If a lint definition's version doesn't match the changelog you will see an error
122+
pointing to the definition that needs changing.
125123

126124
[changelog]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md
127125
[forge]: https://forge.rust-lang.org/

clippy_lints/src/almost_complete_range.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ declare_clippy_lint! {
2323
/// ```no_run
2424
/// let _ = 'a'..='z';
2525
/// ```
26-
#[clippy::version = "1.68.0"]
26+
#[clippy::version = "1.63.0"]
2727
pub ALMOST_COMPLETE_RANGE,
2828
suspicious,
2929
"almost complete range"

clippy_lints/src/declare_clippy_lint.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ macro_rules! declare_clippy_lint {
77
$level:ident,
88
$lintcategory:expr,
99
$desc:literal,
10-
$version_expr:expr,
11-
$version_lit:literal
10+
$version:literal
1211
$(, $eval_always: literal)?
1312
) => {
1413
rustc_session::declare_tool_lint! {
1514
$(#[doc = $lit])*
16-
#[clippy::version = $version_lit]
15+
#[clippy::version = $version]
1716
pub clippy::$lint_name,
1817
$level,
1918
$desc,
@@ -25,8 +24,9 @@ macro_rules! declare_clippy_lint {
2524
lint: &$lint_name,
2625
category: $lintcategory,
2726
explanation: concat!($($lit,"\n",)*),
28-
location: concat!(file!(), "#L", line!()),
29-
version: $version_expr
27+
file: file!(),
28+
line: line!(),
29+
version: $version,
3030
};
3131
};
3232
(
@@ -40,7 +40,7 @@ macro_rules! declare_clippy_lint {
4040
declare_clippy_lint! {@
4141
$(#[doc = $lit])*
4242
pub $lint_name, Allow, crate::LintCategory::Restriction, $desc,
43-
Some($version), $version
43+
$version
4444
$(, $eval_always)?
4545
}
4646
};
@@ -55,7 +55,7 @@ macro_rules! declare_clippy_lint {
5555
declare_clippy_lint! {@
5656
$(#[doc = $lit])*
5757
pub $lint_name, Warn, crate::LintCategory::Style, $desc,
58-
Some($version), $version
58+
$version
5959
$(, $eval_always)?
6060
}
6161
};
@@ -70,7 +70,7 @@ macro_rules! declare_clippy_lint {
7070
declare_clippy_lint! {@
7171
$(#[doc = $lit])*
7272
pub $lint_name, Deny, crate::LintCategory::Correctness, $desc,
73-
Some($version), $version
73+
$version
7474
$(, $eval_always)?
7575

7676
}
@@ -86,7 +86,7 @@ macro_rules! declare_clippy_lint {
8686
declare_clippy_lint! {@
8787
$(#[doc = $lit])*
8888
pub $lint_name, Warn, crate::LintCategory::Perf, $desc,
89-
Some($version), $version
89+
$version
9090
$(, $eval_always)?
9191
}
9292
};
@@ -101,7 +101,7 @@ macro_rules! declare_clippy_lint {
101101
declare_clippy_lint! {@
102102
$(#[doc = $lit])*
103103
pub $lint_name, Warn, crate::LintCategory::Complexity, $desc,
104-
Some($version), $version
104+
$version
105105
$(, $eval_always)?
106106
}
107107
};
@@ -116,7 +116,7 @@ macro_rules! declare_clippy_lint {
116116
declare_clippy_lint! {@
117117
$(#[doc = $lit])*
118118
pub $lint_name, Warn, crate::LintCategory::Suspicious, $desc,
119-
Some($version), $version
119+
$version
120120
$(, $eval_always)?
121121
}
122122
};
@@ -131,7 +131,7 @@ macro_rules! declare_clippy_lint {
131131
declare_clippy_lint! {@
132132
$(#[doc = $lit])*
133133
pub $lint_name, Allow, crate::LintCategory::Nursery, $desc,
134-
Some($version), $version
134+
$version
135135
$(, $eval_always)?
136136
}
137137
};
@@ -146,7 +146,7 @@ macro_rules! declare_clippy_lint {
146146
declare_clippy_lint! {@
147147
$(#[doc = $lit])*
148148
pub $lint_name, Allow, crate::LintCategory::Pedantic, $desc,
149-
Some($version), $version
149+
$version
150150
$(, $eval_always)?
151151
}
152152
};
@@ -161,7 +161,7 @@ macro_rules! declare_clippy_lint {
161161
declare_clippy_lint! {@
162162
$(#[doc = $lit])*
163163
pub $lint_name, Allow, crate::LintCategory::Cargo, $desc,
164-
Some($version), $version
164+
$version
165165
$(, $eval_always)?
166166
}
167167
};

clippy_lints/src/lib.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,11 @@ pub struct LintInfo {
482482
pub lint: &'static &'static Lint,
483483
category: LintCategory,
484484
pub explanation: &'static str,
485-
/// e.g. `clippy_lints/src/absolute_paths.rs#43`
486-
pub location: &'static str,
487-
pub version: Option<&'static str>,
485+
/// e.g. `clippy_lints/src/absolute_paths.rs`
486+
pub file: &'static str,
487+
/// The line number in `file`
488+
pub line: u32,
489+
pub version: &'static str,
488490
}
489491

490492
impl LintInfo {
@@ -508,6 +510,14 @@ impl LintInfo {
508510
Suspicious => "suspicious",
509511
}
510512
}
513+
514+
pub fn location_terminal(&self) -> String {
515+
format!("{}:{}", self.file, self.line)
516+
}
517+
518+
pub fn location_github(&self) -> String {
519+
format!("{}#L{}", self.file, self.line)
520+
}
511521
}
512522

513523
pub fn explain(name: &str) -> i32 {

clippy_lints/src/unicode.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![expect(clippy::invisible_characters, clippy::non_ascii_literal)]
2+
13
use clippy_utils::diagnostics::span_lint_and_then;
24
use clippy_utils::is_lint_allowed;
35
use clippy_utils::macros::span_is_local;

tests/compile-test.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ impl Flag for DiagnosticCollector {
528528
#[derive(Debug)]
529529
struct LintMetadata {
530530
id: String,
531-
id_location: Option<&'static str>,
531+
id_location: Option<String>,
532532
group: &'static str,
533533
level: &'static str,
534534
docs: String,
@@ -567,11 +567,11 @@ impl LintMetadata {
567567
}
568568
Self {
569569
id: name,
570-
id_location: Some(lint.location),
570+
id_location: Some(lint.location_github()),
571571
group: lint.category_str(),
572572
level: lint.lint.default_level.as_str(),
573573
docs,
574-
version: lint.version.unwrap(),
574+
version: lint.version,
575575
applicability,
576576
}
577577
}

tests/lint-definitions.rs

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#![feature(rustc_private)]
2+
3+
use std::collections::HashMap;
4+
use std::fs;
5+
6+
use clippy_lints::declared_lints::LINTS;
7+
use clippy_lints::deprecated_lints::RENAMED;
8+
use pulldown_cmark::{Event, HeadingLevel, Parser, Tag, TagEnd};
9+
use test_utils::IS_RUSTC_TEST_SUITE;
10+
11+
mod test_utils;
12+
13+
#[test]
14+
fn versions_match_changelog() {
15+
if IS_RUSTC_TEST_SUITE {
16+
return;
17+
}
18+
19+
let changelog = fs::read_to_string("CHANGELOG.md").unwrap();
20+
21+
let mut versions_by_name: HashMap<_, _> = LINTS.iter().map(|&lint| (lint.name_lower(), lint)).collect();
22+
23+
for (from, to) in RENAMED {
24+
let from = from.strip_prefix("clippy::").unwrap();
25+
if let Some(to) = to.strip_prefix("clippy::") {
26+
versions_by_name.insert(from.to_owned(), versions_by_name[to]);
27+
}
28+
}
29+
30+
let mut heading = None;
31+
let mut changelog_version = None;
32+
let mut in_new_lints = true;
33+
let mut checked = 0;
34+
35+
for event in Parser::new(&changelog) {
36+
match event {
37+
Event::Start(Tag::Heading { level, .. }) => {
38+
in_new_lints = false;
39+
heading = Some(level);
40+
},
41+
Event::End(TagEnd::Heading(_)) => heading = None,
42+
Event::Text(text) => match heading {
43+
Some(HeadingLevel::H2) => {
44+
if let Some(v) = text.strip_prefix("Rust ") {
45+
changelog_version = Some(v.to_owned());
46+
}
47+
},
48+
Some(HeadingLevel::H3) => {
49+
in_new_lints = text.eq_ignore_ascii_case("new lints");
50+
},
51+
_ => {},
52+
},
53+
Event::Start(Tag::Link { id, .. }) if in_new_lints => {
54+
if let Some(name) = id.strip_prefix('`')
55+
&& let Some(name) = name.strip_suffix('`')
56+
&& let Some(&lint) = versions_by_name.get(name)
57+
{
58+
let lint_version = lint.version.strip_suffix(".0").unwrap();
59+
let changelog_version = changelog_version.as_deref().unwrap();
60+
assert_eq!(
61+
lint_version,
62+
changelog_version,
63+
"{name} has version {lint_version} but appears in the changelog for {changelog_version}\n\
64+
\n\
65+
update {} to `#[clippy::version = \"{changelog_version}.0\"]`",
66+
lint.location_terminal(),
67+
);
68+
checked += 1;
69+
}
70+
},
71+
_ => {},
72+
}
73+
}
74+
75+
assert!(
76+
checked > 400,
77+
"only checked {checked} versions, did the changelog format change?"
78+
);
79+
}

0 commit comments

Comments
 (0)