Skip to content

Commit 0a7b328

Browse files
Upgrade toml to 0.9.7 and remove the serde feature (#15806)
With this and #13084 our toml version will be pushed to `0.9.7`. This is different from rustc's version, but the changes in #13084 already require an incompatible version. The `serde` feature is also removed since it was only used in one spot with a mostly trivial replacement. changelog: none
2 parents 8229701 + 3d2a8df commit 0a7b328

File tree

5 files changed

+119
-105
lines changed

5 files changed

+119
-105
lines changed

Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,18 @@ ui_test = "0.30.2"
3838
regex = "1.5.5"
3939
serde = { version = "1.0.145", features = ["derive"] }
4040
serde_json = "1.0.122"
41-
toml = "0.7.3"
4241
walkdir = "2.3"
4342
filetime = "0.2.9"
4443
itertools = "0.12"
4544
pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] }
4645
askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] }
4746

47+
[dev-dependencies.toml]
48+
version = "0.9.7"
49+
default-features = false
50+
# preserve_order keeps diagnostic output in file order
51+
features = ["parse", "preserve_order"]
52+
4853
[build-dependencies]
4954
rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
5055

clippy_lints/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,17 @@ itertools = "0.12"
1818
quine-mc_cluskey = "0.2"
1919
regex-syntax = "0.8"
2020
serde = { version = "1.0", features = ["derive"] }
21-
toml = "0.7.3"
2221
unicode-normalization = "0.1"
2322
unicode-script = { version = "0.5", default-features = false }
2423
semver = "1.0"
2524
url = "2.2"
2625

26+
[dependencies.toml]
27+
version = "0.9.7"
28+
default-features = false
29+
# preserve_order keeps diagnostic output in file order
30+
features = ["parse", "preserve_order"]
31+
2732
[dev-dependencies]
2833
walkdir = "2.3"
2934

clippy_lints/src/cargo/lint_groups_priority.rs

Lines changed: 90 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -4,142 +4,103 @@ use rustc_data_structures::fx::FxHashSet;
44
use rustc_errors::Applicability;
55
use rustc_lint::{LateContext, unerased_lint_store};
66
use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
7-
use serde::{Deserialize, Serialize};
8-
use std::collections::BTreeMap;
97
use std::ops::Range;
108
use std::path::Path;
119
use toml::Spanned;
10+
use toml::de::{DeTable, DeValue};
1211

13-
#[derive(Deserialize, Serialize, Debug)]
14-
struct LintConfigTable {
15-
level: String,
16-
priority: Option<i64>,
12+
fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
13+
Span::new(
14+
file.start_pos + BytePos::from_usize(range.start),
15+
file.start_pos + BytePos::from_usize(range.end),
16+
SyntaxContext::root(),
17+
None,
18+
)
1719
}
1820

19-
#[derive(Deserialize, Debug)]
20-
#[serde(untagged)]
21-
enum LintConfig {
22-
Level(String),
23-
Table(LintConfigTable),
21+
struct LintConfig<'a> {
22+
sp: Range<usize>,
23+
level: &'a str,
24+
priority: Option<i64>,
2425
}
25-
26-
impl LintConfig {
27-
fn level(&self) -> &str {
28-
match self {
29-
LintConfig::Level(level) => level,
30-
LintConfig::Table(table) => &table.level,
31-
}
32-
}
33-
26+
impl<'a> LintConfig<'a> {
3427
fn priority(&self) -> i64 {
35-
match self {
36-
LintConfig::Level(_) => 0,
37-
LintConfig::Table(table) => table.priority.unwrap_or(0),
38-
}
28+
self.priority.unwrap_or(0)
3929
}
4030

4131
fn is_implicit(&self) -> bool {
42-
if let LintConfig::Table(table) = self {
43-
table.priority.is_none()
44-
} else {
45-
true
46-
}
32+
self.priority.is_none()
4733
}
48-
}
49-
50-
type LintTable = BTreeMap<Spanned<String>, Spanned<LintConfig>>;
51-
52-
#[derive(Deserialize, Debug, Default)]
53-
struct Lints {
54-
#[serde(default)]
55-
rust: LintTable,
56-
#[serde(default)]
57-
clippy: LintTable,
58-
}
59-
60-
#[derive(Deserialize, Debug, Default)]
61-
struct Workspace {
62-
#[serde(default)]
63-
lints: Lints,
64-
}
6534

66-
#[derive(Deserialize, Debug)]
67-
struct CargoToml {
68-
#[serde(default)]
69-
lints: Lints,
70-
#[serde(default)]
71-
workspace: Workspace,
72-
}
73-
74-
fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
75-
Span::new(
76-
file.start_pos + BytePos::from_usize(range.start),
77-
file.start_pos + BytePos::from_usize(range.end),
78-
SyntaxContext::root(),
79-
None,
80-
)
35+
fn parse(value: &'a Spanned<DeValue<'a>>) -> Option<Self> {
36+
let sp = value.span();
37+
let (level, priority) = match value.get_ref() {
38+
DeValue::String(level) => (&**level, None),
39+
DeValue::Table(tbl) => {
40+
let level = tbl.get("level")?.get_ref().as_str()?;
41+
let priority = if let Some(priority) = tbl.get("priority") {
42+
let priority = priority.get_ref().as_integer()?;
43+
Some(i64::from_str_radix(priority.as_str(), priority.radix()).ok()?)
44+
} else {
45+
None
46+
};
47+
(level, priority)
48+
},
49+
_ => return None,
50+
};
51+
Some(Self { sp, level, priority })
52+
}
8153
}
8254

83-
fn check_table(cx: &LateContext<'_>, table: LintTable, known_groups: &FxHashSet<&str>, file: &SourceFile) {
55+
fn check_table(cx: &LateContext<'_>, table: &DeTable<'_>, known_groups: &FxHashSet<&str>, file: &SourceFile) {
8456
let mut lints = Vec::new();
8557
let mut groups = Vec::new();
8658
for (name, config) in table {
87-
if name.get_ref() == "warnings" {
88-
continue;
89-
}
90-
91-
if known_groups.contains(name.get_ref().as_str()) {
92-
groups.push((name, config));
93-
} else {
94-
lints.push((name, config.into_inner()));
59+
if name.get_ref() != "warnings"
60+
&& let Some(config) = LintConfig::parse(config)
61+
{
62+
if known_groups.contains(&**name.get_ref()) {
63+
groups.push((name, config));
64+
} else {
65+
lints.push((name, config));
66+
}
9567
}
9668
}
9769

9870
for (group, group_config) in groups {
99-
let priority = group_config.get_ref().priority();
100-
let level = group_config.get_ref().level();
101-
if let Some((conflict, _)) = lints
102-
.iter()
103-
.rfind(|(_, lint_config)| lint_config.priority() == priority && lint_config.level() != level)
104-
{
71+
if let Some((conflict, _)) = lints.iter().rfind(|(_, lint_config)| {
72+
lint_config.priority() == group_config.priority() && lint_config.level != group_config.level
73+
}) {
10574
span_lint_and_then(
10675
cx,
10776
LINT_GROUPS_PRIORITY,
10877
toml_span(group.span(), file),
10978
format!(
110-
"lint group `{}` has the same priority ({priority}) as a lint",
111-
group.as_ref()
79+
"lint group `{}` has the same priority ({}) as a lint",
80+
group.as_ref(),
81+
group_config.priority(),
11282
),
11383
|diag| {
114-
let config_span = toml_span(group_config.span(), file);
84+
let config_span = toml_span(group_config.sp.clone(), file);
11585

116-
if group_config.as_ref().is_implicit() {
86+
if group_config.is_implicit() {
11787
diag.span_label(config_span, "has an implicit priority of 0");
11888
}
11989
diag.span_label(toml_span(conflict.span(), file), "has the same priority as this lint");
12090
diag.note("the order of the lints in the table is ignored by Cargo");
12191

122-
let mut suggestion = String::new();
12392
let low_priority = lints
12493
.iter()
125-
.map(|(_, config)| config.priority().saturating_sub(1))
94+
.map(|(_, lint_config)| lint_config.priority().saturating_sub(1))
12695
.min()
12796
.unwrap_or(-1);
128-
Serialize::serialize(
129-
&LintConfigTable {
130-
level: level.into(),
131-
priority: Some(low_priority),
132-
},
133-
toml::ser::ValueSerializer::new(&mut suggestion),
134-
)
135-
.unwrap();
13697
diag.span_suggestion_verbose(
13798
config_span,
13899
format!(
139100
"to have lints override the group set `{}` to a lower priority",
140101
group.as_ref()
141102
),
142-
suggestion,
103+
format!("{{ level = {:?}, priority = {low_priority} }}", group_config.level,),
143104
Applicability::MaybeIncorrect,
144105
);
145106
},
@@ -148,10 +109,29 @@ fn check_table(cx: &LateContext<'_>, table: LintTable, known_groups: &FxHashSet<
148109
}
149110
}
150111

112+
struct LintTbls<'a> {
113+
rust: Option<&'a DeTable<'a>>,
114+
clippy: Option<&'a DeTable<'a>>,
115+
}
116+
fn get_lint_tbls<'a>(tbl: &'a DeTable<'a>) -> LintTbls<'a> {
117+
if let Some(lints) = tbl.get("lints")
118+
&& let Some(lints) = lints.get_ref().as_table()
119+
{
120+
let rust = lints.get("rust").and_then(|x| x.get_ref().as_table());
121+
let clippy = lints.get("clippy").and_then(|x| x.get_ref().as_table());
122+
LintTbls { rust, clippy }
123+
} else {
124+
LintTbls {
125+
rust: None,
126+
clippy: None,
127+
}
128+
}
129+
}
130+
151131
pub fn check(cx: &LateContext<'_>) {
152132
if let Ok(file) = cx.tcx.sess.source_map().load_file(Path::new("Cargo.toml"))
153133
&& let Some(src) = file.src.as_deref()
154-
&& let Ok(cargo_toml) = toml::from_str::<CargoToml>(src)
134+
&& let Ok(cargo_toml) = DeTable::parse(src)
155135
{
156136
let mut rustc_groups = FxHashSet::default();
157137
let mut clippy_groups = FxHashSet::default();
@@ -167,9 +147,23 @@ pub fn check(cx: &LateContext<'_>) {
167147
}
168148
}
169149

170-
check_table(cx, cargo_toml.lints.rust, &rustc_groups, &file);
171-
check_table(cx, cargo_toml.lints.clippy, &clippy_groups, &file);
172-
check_table(cx, cargo_toml.workspace.lints.rust, &rustc_groups, &file);
173-
check_table(cx, cargo_toml.workspace.lints.clippy, &clippy_groups, &file);
150+
let lints = get_lint_tbls(cargo_toml.get_ref());
151+
if let Some(lints) = lints.rust {
152+
check_table(cx, lints, &rustc_groups, &file);
153+
}
154+
if let Some(lints) = lints.clippy {
155+
check_table(cx, lints, &clippy_groups, &file);
156+
}
157+
if let Some(tbl) = cargo_toml.get_ref().get("workspace")
158+
&& let Some(tbl) = tbl.get_ref().as_table()
159+
{
160+
let lints = get_lint_tbls(tbl);
161+
if let Some(lints) = lints.rust {
162+
check_table(cx, lints, &rustc_groups, &file);
163+
}
164+
if let Some(lints) = lints.clippy {
165+
check_table(cx, lints, &clippy_groups, &file);
166+
}
167+
}
174168
}
175169
}

lintcheck/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ serde = { version = "1.0", features = ["derive"] }
2222
serde_json = "1.0.85"
2323
strip-ansi-escapes = "0.2.0"
2424
tar = "0.4"
25-
toml = "0.7.3"
25+
toml = "0.9.7"
2626
ureq = { version = "2.2", features = ["json"] }
2727
walkdir = "2.3"

tests/compile-test.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -405,11 +405,18 @@ fn ui_cargo_toml_metadata() {
405405
continue;
406406
}
407407

408-
let toml = fs::read_to_string(path).unwrap().parse::<toml::Value>().unwrap();
409-
410-
let package = toml.as_table().unwrap().get("package").unwrap().as_table().unwrap();
411-
412-
let name = package.get("name").unwrap().as_str().unwrap().replace('-', "_");
408+
let toml = fs::read_to_string(path).unwrap();
409+
let toml = toml::de::DeTable::parse(&toml).unwrap();
410+
411+
let package = toml.get_ref().get("package").unwrap().get_ref().as_table().unwrap();
412+
413+
let name = package
414+
.get("name")
415+
.unwrap()
416+
.as_ref()
417+
.as_str()
418+
.unwrap()
419+
.replace('-', "_");
413420
assert!(
414421
path.parent()
415422
.unwrap()
@@ -421,7 +428,10 @@ fn ui_cargo_toml_metadata() {
421428
path.display(),
422429
);
423430

424-
let publish = package.get("publish").and_then(toml::Value::as_bool).unwrap_or(true);
431+
let publish = package
432+
.get("publish")
433+
.and_then(|x| x.get_ref().as_bool())
434+
.unwrap_or(true);
425435
assert!(
426436
!publish || publish_exceptions.contains(&path.parent().unwrap().to_path_buf()),
427437
"`{}` lacks `publish = false`",

0 commit comments

Comments
 (0)