Skip to content

Commit e101222

Browse files
committed
Add support for nightly-only lints
1 parent f7e2cb4 commit e101222

33 files changed

+196
-211
lines changed

clippy_dev/src/new_lint.rs

-22
Original file line numberDiff line numberDiff line change
@@ -163,26 +163,6 @@ fn to_camel_case(name: &str) -> String {
163163
.collect()
164164
}
165165

166-
pub(crate) fn get_stabilization_version() -> String {
167-
fn parse_manifest(contents: &str) -> Option<String> {
168-
let version = contents
169-
.lines()
170-
.filter_map(|l| l.split_once('='))
171-
.find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))?;
172-
let Some(("0", version)) = version.get(1..version.len() - 1)?.split_once('.') else {
173-
return None;
174-
};
175-
let (minor, patch) = version.split_once('.')?;
176-
Some(format!(
177-
"{}.{}.0",
178-
minor.parse::<u32>().ok()?,
179-
patch.parse::<u32>().ok()?
180-
))
181-
}
182-
let contents = fs::read_to_string("Cargo.toml").expect("Unable to read `Cargo.toml`");
183-
parse_manifest(&contents).expect("Unable to find package version in `Cargo.toml`")
184-
}
185-
186166
fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
187167
let mut contents = format!(
188168
indoc! {"
@@ -327,13 +307,11 @@ fn get_lint_declaration(name_upper: &str, category: &str) -> String {
327307
/// ```rust
328308
/// // example code which does not raise clippy warning
329309
/// ```
330-
#[clippy::version = "{version}"]
331310
pub {name_upper},
332311
{category},
333312
"default lint description"
334313
}}
335314
"#},
336-
version = get_stabilization_version(),
337315
name_upper = name_upper,
338316
category = category,
339317
)

clippy_dev/src/update_lints.rs

+84-18
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,6 @@ fn declare_deprecated(name: &str, path: &Path, reason: &str) -> io::Result<()> {
491491

492492
file.seek(SeekFrom::End(0))?;
493493

494-
let version = crate::new_lint::get_stabilization_version();
495494
let deprecation_reason = if reason == DEFAULT_DEPRECATION_REASON {
496495
"TODO"
497496
} else {
@@ -508,14 +507,13 @@ fn declare_deprecated(name: &str, path: &Path, reason: &str) -> io::Result<()> {
508507
///
509508
/// ### Deprecation reason
510509
/// {}
511-
#[clippy::version = \"{}\"]
510+
#[clippy::version = \"nightly\"]
512511
pub {},
513512
\"{}\"
514513
}}
515514
516515
",
517516
deprecation_reason,
518-
version,
519517
name,
520518
reason,
521519
)
@@ -588,17 +586,26 @@ struct Lint {
588586
group: String,
589587
desc: String,
590588
module: String,
589+
has_version: bool,
591590
declaration_range: Range<usize>,
592591
}
593592

594593
impl Lint {
595594
#[must_use]
596-
fn new(name: &str, group: &str, desc: &str, module: &str, declaration_range: Range<usize>) -> Self {
595+
fn new(
596+
name: &str,
597+
group: &str,
598+
desc: &str,
599+
module: &str,
600+
has_version: bool,
601+
declaration_range: Range<usize>,
602+
) -> Self {
597603
Self {
598604
name: name.to_lowercase(),
599605
group: group.into(),
600606
desc: remove_line_splices(desc),
601607
module: module.into(),
608+
has_version,
602609
declaration_range,
603610
}
604611
}
@@ -657,7 +664,9 @@ impl RenamedLint {
657664

658665
/// Generates the code for registering a group
659666
fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lint>) -> String {
660-
let mut details: Vec<_> = lints.map(|l| (&l.module, l.name.to_uppercase())).collect();
667+
let mut details: Vec<_> = lints
668+
.map(|l| (&l.module, l.name.to_uppercase(), l.has_version))
669+
.collect();
661670
details.sort_unstable();
662671

663672
let mut output = GENERATED_FILE_COMMENT.to_string();
@@ -667,8 +676,14 @@ fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lin
667676
"store.register_group(true, \"clippy::{0}\", Some(\"clippy_{0}\"), vec![",
668677
group_name
669678
);
670-
for (module, name) in details {
671-
let _ = writeln!(output, " LintId::of({}::{}),", module, name);
679+
for (module, name, has_version) in details {
680+
let _ = writeln!(
681+
output,
682+
" {}LintId::of({}::{}),",
683+
if has_version { "" } else { "#[cfg(nightly)] " },
684+
module,
685+
name,
686+
);
672687
}
673688
output.push_str("])\n");
674689

@@ -858,21 +873,22 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
858873
.filter(|t| !matches!(t.token_kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
859874
// matches `!{`
860875
match_tokens!(iter, Bang OpenBrace);
861-
match iter.next() {
876+
let has_version = match iter.next() {
862877
// #[clippy::version = "version"] pub
863878
Some(LintDeclSearchResult {
864879
token_kind: TokenKind::Pound,
865880
..
866881
}) => {
867882
match_tokens!(iter, OpenBracket Ident Colon Colon Ident Eq Literal{..} CloseBracket Ident);
883+
true
868884
},
869885
// pub
870886
Some(LintDeclSearchResult {
871887
token_kind: TokenKind::Ident,
872888
..
873-
}) => (),
889+
}) => false,
874890
_ => continue,
875-
}
891+
};
876892

877893
let (name, group, desc) = match_tokens!(
878894
iter,
@@ -890,7 +906,7 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
890906
..
891907
}) = iter.next()
892908
{
893-
lints.push(Lint::new(name, group, desc, module, start..range.end));
909+
lints.push(Lint::new(name, group, desc, module, has_version, start..range.end));
894910
}
895911
}
896912
}
@@ -1115,13 +1131,15 @@ mod tests {
11151131
"style",
11161132
"\"really long text\"",
11171133
"module_name",
1134+
true,
11181135
Range::default(),
11191136
),
11201137
Lint::new(
11211138
"doc_markdown",
11221139
"pedantic",
11231140
"\"single line\"",
11241141
"module_name",
1142+
true,
11251143
Range::default(),
11261144
),
11271145
];
@@ -1161,20 +1179,23 @@ mod tests {
11611179
"Not Deprecated",
11621180
"\"abc\"",
11631181
"module_name",
1182+
true,
11641183
Range::default(),
11651184
),
11661185
Lint::new(
11671186
"should_assert_eq2",
11681187
"internal",
11691188
"\"abc\"",
11701189
"module_name",
1190+
true,
11711191
Range::default(),
11721192
),
11731193
Lint::new(
11741194
"should_assert_eq2",
11751195
"internal_style",
11761196
"\"abc\"",
11771197
"module_name",
1198+
true,
11781199
Range::default(),
11791200
),
11801201
];
@@ -1183,6 +1204,7 @@ mod tests {
11831204
"Not Deprecated",
11841205
"\"abc\"",
11851206
"module_name",
1207+
true,
11861208
Range::default(),
11871209
)];
11881210
assert_eq!(expected, Lint::usable_lints(&lints));
@@ -1191,22 +1213,51 @@ mod tests {
11911213
#[test]
11921214
fn test_by_lint_group() {
11931215
let lints = vec![
1194-
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
1216+
Lint::new(
1217+
"should_assert_eq",
1218+
"group1",
1219+
"\"abc\"",
1220+
"module_name",
1221+
true,
1222+
Range::default(),
1223+
),
11951224
Lint::new(
11961225
"should_assert_eq2",
11971226
"group2",
11981227
"\"abc\"",
11991228
"module_name",
1229+
true,
1230+
Range::default(),
1231+
),
1232+
Lint::new(
1233+
"incorrect_match",
1234+
"group1",
1235+
"\"abc\"",
1236+
"module_name",
1237+
true,
12001238
Range::default(),
12011239
),
1202-
Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
12031240
];
12041241
let mut expected: HashMap<String, Vec<Lint>> = HashMap::new();
12051242
expected.insert(
12061243
"group1".to_string(),
12071244
vec![
1208-
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
1209-
Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
1245+
Lint::new(
1246+
"should_assert_eq",
1247+
"group1",
1248+
"\"abc\"",
1249+
"module_name",
1250+
true,
1251+
Range::default(),
1252+
),
1253+
Lint::new(
1254+
"incorrect_match",
1255+
"group1",
1256+
"\"abc\"",
1257+
"module_name",
1258+
true,
1259+
Range::default(),
1260+
),
12101261
],
12111262
);
12121263
expected.insert(
@@ -1216,6 +1267,7 @@ mod tests {
12161267
"group2",
12171268
"\"abc\"",
12181269
"module_name",
1270+
true,
12191271
Range::default(),
12201272
)],
12211273
);
@@ -1255,9 +1307,23 @@ mod tests {
12551307
#[test]
12561308
fn test_gen_lint_group_list() {
12571309
let lints = vec![
1258-
Lint::new("abc", "group1", "\"abc\"", "module_name", Range::default()),
1259-
Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
1260-
Lint::new("internal", "internal_style", "\"abc\"", "module_name", Range::default()),
1310+
Lint::new("abc", "group1", "\"abc\"", "module_name", true, Range::default()),
1311+
Lint::new(
1312+
"should_assert_eq",
1313+
"group1",
1314+
"\"abc\"",
1315+
"module_name",
1316+
true,
1317+
Range::default(),
1318+
),
1319+
Lint::new(
1320+
"internal",
1321+
"internal_style",
1322+
"\"abc\"",
1323+
"module_name",
1324+
true,
1325+
Range::default(),
1326+
),
12611327
];
12621328
let expected = GENERATED_FILE_COMMENT.to_string()
12631329
+ &[

clippy_lints/build.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL");
3+
if option_env!("CFG_RELEASE_CHANNEL").map_or(true, |c| c == "nightly" || c == "dev") {
4+
println!("cargo:rustc-cfg=nightly");
5+
}
6+
}

clippy_lints/src/lib.register_internal.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@
33
// Manual edits will be overwritten.
44

55
store.register_group(true, "clippy::internal", Some("clippy_internal"), vec![
6-
LintId::of(utils::internal_lints::CLIPPY_LINTS_INTERNAL),
7-
LintId::of(utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS),
8-
LintId::of(utils::internal_lints::COMPILER_LINT_FUNCTIONS),
9-
LintId::of(utils::internal_lints::DEFAULT_DEPRECATION_REASON),
10-
LintId::of(utils::internal_lints::DEFAULT_LINT),
11-
LintId::of(utils::internal_lints::IF_CHAIN_STYLE),
12-
LintId::of(utils::internal_lints::INTERNING_DEFINED_SYMBOL),
13-
LintId::of(utils::internal_lints::INVALID_CLIPPY_VERSION_ATTRIBUTE),
14-
LintId::of(utils::internal_lints::INVALID_PATHS),
15-
LintId::of(utils::internal_lints::LINT_WITHOUT_LINT_PASS),
16-
LintId::of(utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM),
17-
LintId::of(utils::internal_lints::MISSING_CLIPPY_VERSION_ATTRIBUTE),
18-
LintId::of(utils::internal_lints::MISSING_MSRV_ATTR_IMPL),
19-
LintId::of(utils::internal_lints::OUTER_EXPN_EXPN_DATA),
20-
LintId::of(utils::internal_lints::PRODUCE_ICE),
21-
LintId::of(utils::internal_lints::UNNECESSARY_SYMBOL_STR),
6+
#[cfg(nightly)] LintId::of(utils::internal_lints::CLIPPY_LINTS_INTERNAL),
7+
#[cfg(nightly)] LintId::of(utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS),
8+
#[cfg(nightly)] LintId::of(utils::internal_lints::COMPILER_LINT_FUNCTIONS),
9+
#[cfg(nightly)] LintId::of(utils::internal_lints::DEFAULT_DEPRECATION_REASON),
10+
#[cfg(nightly)] LintId::of(utils::internal_lints::DEFAULT_LINT),
11+
#[cfg(nightly)] LintId::of(utils::internal_lints::IF_CHAIN_STYLE),
12+
#[cfg(nightly)] LintId::of(utils::internal_lints::INTERNING_DEFINED_SYMBOL),
13+
#[cfg(nightly)] LintId::of(utils::internal_lints::INVALID_CLIPPY_VERSION_ATTRIBUTE),
14+
#[cfg(nightly)] LintId::of(utils::internal_lints::INVALID_PATHS),
15+
#[cfg(nightly)] LintId::of(utils::internal_lints::LINT_WITHOUT_LINT_PASS),
16+
#[cfg(nightly)] LintId::of(utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM),
17+
#[cfg(nightly)] LintId::of(utils::internal_lints::MISSING_MSRV_ATTR_IMPL),
18+
#[cfg(nightly)] LintId::of(utils::internal_lints::OUTER_EXPN_EXPN_DATA),
19+
#[cfg(nightly)] LintId::of(utils::internal_lints::PRODUCE_ICE),
20+
#[cfg(nightly)] LintId::of(utils::internal_lints::UNNECESSARY_SYMBOL_STR),
2221
])

clippy_lints/src/lib.register_lints.rs

-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ store.register_lints(&[
2626
#[cfg(feature = "internal")]
2727
utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM,
2828
#[cfg(feature = "internal")]
29-
utils::internal_lints::MISSING_CLIPPY_VERSION_ATTRIBUTE,
30-
#[cfg(feature = "internal")]
3129
utils::internal_lints::MISSING_MSRV_ATTR_IMPL,
3230
#[cfg(feature = "internal")]
3331
utils::internal_lints::OUTER_EXPN_EXPN_DATA,

0 commit comments

Comments
 (0)