Auto merge of #13402 - epage:add, r=weihanglo

fix: Don't duplicate comments when editing TOML

### What does this PR try to resolve?

`toml_edit` <0.22 has a bug that will cause
```toml
[lints]
rust.unsafe_op_in_unsafe_fn = "deny"

rust.explicit_outlives_requirements = "warn"
# rust.unused_crate_dependencies = "warn"

clippy.cast_lossless = "warn"
clippy.doc_markdown = "warn"
clippy.exhaustive_enums = "warn"
```
to be written out as
```toml
[lints]
rust.unsafe_op_in_unsafe_fn = "deny"
rust.explicit_outlives_requirements = "warn"
# rust.unused_crate_dependencies = "warn"

clippy.cast_lossless = "warn"
# rust.unused_crate_dependencies = "warn"

clippy.doc_markdown = "warn"
# rust.unused_crate_dependencies = "warn"

clippy.exhaustive_enums = "warn"
```
when it is parsed and then saved.

See toml-rs/toml#673

This affects any format-preserving edits we do, including:
- `cargo add`
- `cargo remove`
- `cargo init` / `cargo new` editing the workspace

### How should we test and review this PR?

I didn't add any tests as this is covered by `toml_edit`s tests (we already don't cover a fraction of the edit preserving tests it has)

### Additional information
This commit is contained in:
bors 2024-02-07 16:23:04 +00:00
commit d7d48e4598
3 changed files with 19 additions and 12 deletions

8
Cargo.lock generated
View File

@ -3360,9 +3360,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "toml"
version = "0.8.9"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6a4b9e8023eb94392d3dca65d717c53abc5dad49c07cb65bb8fcd87115fa325"
checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290"
dependencies = [
"serde",
"serde_spanned",
@ -3381,9 +3381,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.21.1"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951"
dependencies = [
"indexmap",
"serde",

View File

@ -96,8 +96,8 @@ tar = { version = "0.4.40", default-features = false }
tempfile = "3.9.0"
thiserror = "1.0.56"
time = { version = "0.3", features = ["parsing", "formatting", "serde"] }
toml = "0.8.9"
toml_edit = { version = "0.21.1", features = ["serde"] }
toml = "0.8.10"
toml_edit = { version = "0.22.4", features = ["serde"] }
tracing = "0.1.40" # be compatible with rustc_log: https://github.com/rust-lang/rust/blob/e51e98dde6a/compiler/rustc_log/Cargo.toml#L9
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
unicase = "2.7.0"

View File

@ -1349,11 +1349,14 @@ impl Config {
let doc: toml_edit::Document = arg.parse().with_context(|| {
format!("failed to parse value from --config argument `{arg}` as a dotted key expression")
})?;
fn non_empty(d: Option<&toml_edit::RawString>) -> bool {
d.map_or(false, |p| !p.as_str().unwrap_or_default().trim().is_empty())
}
fn non_empty_decor(d: &toml_edit::Decor) -> bool {
d.prefix()
.map_or(false, |p| !p.as_str().unwrap_or_default().trim().is_empty())
|| d.suffix()
.map_or(false, |s| !s.as_str().unwrap_or_default().trim().is_empty())
non_empty(d.prefix()) || non_empty(d.suffix())
}
fn non_empty_key_decor(k: &toml_edit::Key) -> bool {
non_empty_decor(k.leaf_decor()) || non_empty_decor(k.dotted_decor())
}
let ok = {
let mut got_to_value = false;
@ -1367,7 +1370,7 @@ impl Config {
let (k, n) = table.iter().next().expect("len() == 1 above");
match n {
Item::Table(nt) => {
if table.key_decor(k).map_or(false, non_empty_decor)
if table.key(k).map_or(false, non_empty_key_decor)
|| non_empty_decor(nt.decor())
{
bail!(
@ -1384,7 +1387,11 @@ impl Config {
);
}
Item::Value(v) => {
if non_empty_decor(v.decor()) {
if table
.key(k)
.map_or(false, |k| non_empty(k.leaf_decor().prefix()))
|| non_empty_decor(v.decor())
{
bail!(
"--config argument `{arg}` \
includes non-whitespace decoration"