Upgrade toml to 0.9.7 and remove the serde feature.
This commit is contained in:
parent
6cc8f8dbaa
commit
3d2a8df077
5 changed files with 119 additions and 105 deletions
|
|
@ -38,13 +38,18 @@ ui_test = "0.30.2"
|
|||
regex = "1.5.5"
|
||||
serde = { version = "1.0.145", features = ["derive"] }
|
||||
serde_json = "1.0.122"
|
||||
toml = "0.7.3"
|
||||
walkdir = "2.3"
|
||||
filetime = "0.2.9"
|
||||
itertools = "0.12"
|
||||
pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] }
|
||||
askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] }
|
||||
|
||||
[dev-dependencies.toml]
|
||||
version = "0.9.7"
|
||||
default-features = false
|
||||
# preserve_order keeps diagnostic output in file order
|
||||
features = ["parse", "preserve_order"]
|
||||
|
||||
[build-dependencies]
|
||||
rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
|
||||
|
||||
|
|
|
|||
|
|
@ -18,12 +18,17 @@ itertools = "0.12"
|
|||
quine-mc_cluskey = "0.2"
|
||||
regex-syntax = "0.8"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.7.3"
|
||||
unicode-normalization = "0.1"
|
||||
unicode-script = { version = "0.5", default-features = false }
|
||||
semver = "1.0"
|
||||
url = "2.2"
|
||||
|
||||
[dependencies.toml]
|
||||
version = "0.9.7"
|
||||
default-features = false
|
||||
# preserve_order keeps diagnostic output in file order
|
||||
features = ["parse", "preserve_order"]
|
||||
|
||||
[dev-dependencies]
|
||||
walkdir = "2.3"
|
||||
|
||||
|
|
|
|||
|
|
@ -4,72 +4,10 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{LateContext, unerased_lint_store};
|
||||
use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use std::ops::Range;
|
||||
use std::path::Path;
|
||||
use toml::Spanned;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
struct LintConfigTable {
|
||||
level: String,
|
||||
priority: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
enum LintConfig {
|
||||
Level(String),
|
||||
Table(LintConfigTable),
|
||||
}
|
||||
|
||||
impl LintConfig {
|
||||
fn level(&self) -> &str {
|
||||
match self {
|
||||
LintConfig::Level(level) => level,
|
||||
LintConfig::Table(table) => &table.level,
|
||||
}
|
||||
}
|
||||
|
||||
fn priority(&self) -> i64 {
|
||||
match self {
|
||||
LintConfig::Level(_) => 0,
|
||||
LintConfig::Table(table) => table.priority.unwrap_or(0),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_implicit(&self) -> bool {
|
||||
if let LintConfig::Table(table) = self {
|
||||
table.priority.is_none()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type LintTable = BTreeMap<Spanned<String>, Spanned<LintConfig>>;
|
||||
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
struct Lints {
|
||||
#[serde(default)]
|
||||
rust: LintTable,
|
||||
#[serde(default)]
|
||||
clippy: LintTable,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Default)]
|
||||
struct Workspace {
|
||||
#[serde(default)]
|
||||
lints: Lints,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct CargoToml {
|
||||
#[serde(default)]
|
||||
lints: Lints,
|
||||
#[serde(default)]
|
||||
workspace: Workspace,
|
||||
}
|
||||
use toml::de::{DeTable, DeValue};
|
||||
|
||||
fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
|
||||
Span::new(
|
||||
|
|
@ -80,66 +18,89 @@ fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
|
|||
)
|
||||
}
|
||||
|
||||
fn check_table(cx: &LateContext<'_>, table: LintTable, known_groups: &FxHashSet<&str>, file: &SourceFile) {
|
||||
struct LintConfig<'a> {
|
||||
sp: Range<usize>,
|
||||
level: &'a str,
|
||||
priority: Option<i64>,
|
||||
}
|
||||
impl<'a> LintConfig<'a> {
|
||||
fn priority(&self) -> i64 {
|
||||
self.priority.unwrap_or(0)
|
||||
}
|
||||
|
||||
fn is_implicit(&self) -> bool {
|
||||
self.priority.is_none()
|
||||
}
|
||||
|
||||
fn parse(value: &'a Spanned<DeValue<'a>>) -> Option<Self> {
|
||||
let sp = value.span();
|
||||
let (level, priority) = match value.get_ref() {
|
||||
DeValue::String(level) => (&**level, None),
|
||||
DeValue::Table(tbl) => {
|
||||
let level = tbl.get("level")?.get_ref().as_str()?;
|
||||
let priority = if let Some(priority) = tbl.get("priority") {
|
||||
let priority = priority.get_ref().as_integer()?;
|
||||
Some(i64::from_str_radix(priority.as_str(), priority.radix()).ok()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
(level, priority)
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
Some(Self { sp, level, priority })
|
||||
}
|
||||
}
|
||||
|
||||
fn check_table(cx: &LateContext<'_>, table: &DeTable<'_>, known_groups: &FxHashSet<&str>, file: &SourceFile) {
|
||||
let mut lints = Vec::new();
|
||||
let mut groups = Vec::new();
|
||||
for (name, config) in table {
|
||||
if name.get_ref() == "warnings" {
|
||||
continue;
|
||||
}
|
||||
|
||||
if known_groups.contains(name.get_ref().as_str()) {
|
||||
groups.push((name, config));
|
||||
} else {
|
||||
lints.push((name, config.into_inner()));
|
||||
if name.get_ref() != "warnings"
|
||||
&& let Some(config) = LintConfig::parse(config)
|
||||
{
|
||||
if known_groups.contains(&**name.get_ref()) {
|
||||
groups.push((name, config));
|
||||
} else {
|
||||
lints.push((name, config));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (group, group_config) in groups {
|
||||
let priority = group_config.get_ref().priority();
|
||||
let level = group_config.get_ref().level();
|
||||
if let Some((conflict, _)) = lints
|
||||
.iter()
|
||||
.rfind(|(_, lint_config)| lint_config.priority() == priority && lint_config.level() != level)
|
||||
{
|
||||
if let Some((conflict, _)) = lints.iter().rfind(|(_, lint_config)| {
|
||||
lint_config.priority() == group_config.priority() && lint_config.level != group_config.level
|
||||
}) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
LINT_GROUPS_PRIORITY,
|
||||
toml_span(group.span(), file),
|
||||
format!(
|
||||
"lint group `{}` has the same priority ({priority}) as a lint",
|
||||
group.as_ref()
|
||||
"lint group `{}` has the same priority ({}) as a lint",
|
||||
group.as_ref(),
|
||||
group_config.priority(),
|
||||
),
|
||||
|diag| {
|
||||
let config_span = toml_span(group_config.span(), file);
|
||||
let config_span = toml_span(group_config.sp.clone(), file);
|
||||
|
||||
if group_config.as_ref().is_implicit() {
|
||||
if group_config.is_implicit() {
|
||||
diag.span_label(config_span, "has an implicit priority of 0");
|
||||
}
|
||||
diag.span_label(toml_span(conflict.span(), file), "has the same priority as this lint");
|
||||
diag.note("the order of the lints in the table is ignored by Cargo");
|
||||
|
||||
let mut suggestion = String::new();
|
||||
let low_priority = lints
|
||||
.iter()
|
||||
.map(|(_, config)| config.priority().saturating_sub(1))
|
||||
.map(|(_, lint_config)| lint_config.priority().saturating_sub(1))
|
||||
.min()
|
||||
.unwrap_or(-1);
|
||||
Serialize::serialize(
|
||||
&LintConfigTable {
|
||||
level: level.into(),
|
||||
priority: Some(low_priority),
|
||||
},
|
||||
toml::ser::ValueSerializer::new(&mut suggestion),
|
||||
)
|
||||
.unwrap();
|
||||
diag.span_suggestion_verbose(
|
||||
config_span,
|
||||
format!(
|
||||
"to have lints override the group set `{}` to a lower priority",
|
||||
group.as_ref()
|
||||
),
|
||||
suggestion,
|
||||
format!("{{ level = {:?}, priority = {low_priority} }}", group_config.level,),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
},
|
||||
|
|
@ -148,10 +109,29 @@ fn check_table(cx: &LateContext<'_>, table: LintTable, known_groups: &FxHashSet<
|
|||
}
|
||||
}
|
||||
|
||||
struct LintTbls<'a> {
|
||||
rust: Option<&'a DeTable<'a>>,
|
||||
clippy: Option<&'a DeTable<'a>>,
|
||||
}
|
||||
fn get_lint_tbls<'a>(tbl: &'a DeTable<'a>) -> LintTbls<'a> {
|
||||
if let Some(lints) = tbl.get("lints")
|
||||
&& let Some(lints) = lints.get_ref().as_table()
|
||||
{
|
||||
let rust = lints.get("rust").and_then(|x| x.get_ref().as_table());
|
||||
let clippy = lints.get("clippy").and_then(|x| x.get_ref().as_table());
|
||||
LintTbls { rust, clippy }
|
||||
} else {
|
||||
LintTbls {
|
||||
rust: None,
|
||||
clippy: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check(cx: &LateContext<'_>) {
|
||||
if let Ok(file) = cx.tcx.sess.source_map().load_file(Path::new("Cargo.toml"))
|
||||
&& let Some(src) = file.src.as_deref()
|
||||
&& let Ok(cargo_toml) = toml::from_str::<CargoToml>(src)
|
||||
&& let Ok(cargo_toml) = DeTable::parse(src)
|
||||
{
|
||||
let mut rustc_groups = FxHashSet::default();
|
||||
let mut clippy_groups = FxHashSet::default();
|
||||
|
|
@ -167,9 +147,23 @@ pub fn check(cx: &LateContext<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
check_table(cx, cargo_toml.lints.rust, &rustc_groups, &file);
|
||||
check_table(cx, cargo_toml.lints.clippy, &clippy_groups, &file);
|
||||
check_table(cx, cargo_toml.workspace.lints.rust, &rustc_groups, &file);
|
||||
check_table(cx, cargo_toml.workspace.lints.clippy, &clippy_groups, &file);
|
||||
let lints = get_lint_tbls(cargo_toml.get_ref());
|
||||
if let Some(lints) = lints.rust {
|
||||
check_table(cx, lints, &rustc_groups, &file);
|
||||
}
|
||||
if let Some(lints) = lints.clippy {
|
||||
check_table(cx, lints, &clippy_groups, &file);
|
||||
}
|
||||
if let Some(tbl) = cargo_toml.get_ref().get("workspace")
|
||||
&& let Some(tbl) = tbl.get_ref().as_table()
|
||||
{
|
||||
let lints = get_lint_tbls(tbl);
|
||||
if let Some(lints) = lints.rust {
|
||||
check_table(cx, lints, &rustc_groups, &file);
|
||||
}
|
||||
if let Some(lints) = lints.clippy {
|
||||
check_table(cx, lints, &clippy_groups, &file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,6 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
serde_json = "1.0.85"
|
||||
strip-ansi-escapes = "0.2.0"
|
||||
tar = "0.4"
|
||||
toml = "0.7.3"
|
||||
toml = "0.9.7"
|
||||
ureq = { version = "2.2", features = ["json"] }
|
||||
walkdir = "2.3"
|
||||
|
|
|
|||
|
|
@ -405,11 +405,18 @@ fn ui_cargo_toml_metadata() {
|
|||
continue;
|
||||
}
|
||||
|
||||
let toml = fs::read_to_string(path).unwrap().parse::<toml::Value>().unwrap();
|
||||
let toml = fs::read_to_string(path).unwrap();
|
||||
let toml = toml::de::DeTable::parse(&toml).unwrap();
|
||||
|
||||
let package = toml.as_table().unwrap().get("package").unwrap().as_table().unwrap();
|
||||
let package = toml.get_ref().get("package").unwrap().get_ref().as_table().unwrap();
|
||||
|
||||
let name = package.get("name").unwrap().as_str().unwrap().replace('-', "_");
|
||||
let name = package
|
||||
.get("name")
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.as_str()
|
||||
.unwrap()
|
||||
.replace('-', "_");
|
||||
assert!(
|
||||
path.parent()
|
||||
.unwrap()
|
||||
|
|
@ -421,7 +428,10 @@ fn ui_cargo_toml_metadata() {
|
|||
path.display(),
|
||||
);
|
||||
|
||||
let publish = package.get("publish").and_then(toml::Value::as_bool).unwrap_or(true);
|
||||
let publish = package
|
||||
.get("publish")
|
||||
.and_then(|x| x.get_ref().as_bool())
|
||||
.unwrap_or(true);
|
||||
assert!(
|
||||
!publish || publish_exceptions.contains(&path.parent().unwrap().to_path_buf()),
|
||||
"`{}` lacks `publish = false`",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue