diff --git a/Cargo.lock b/Cargo.lock index 2691b270d..62e3e4182 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -295,7 +295,7 @@ dependencies = [ "cargo_metadata", "flate2", "tar", - "toml", + "toml 0.9.0", ] [[package]] @@ -369,8 +369,8 @@ dependencies = [ "tempfile", "thiserror 2.0.12", "time", - "toml", - "toml_edit", + "toml 0.9.0", + "toml_edit 0.23.0", "tracing", "tracing-chrome", "tracing-subscriber", @@ -472,7 +472,7 @@ dependencies = [ "snapbox", "tar", "time", - "toml", + "toml 0.9.0", "url", "walkdir", "windows-sys 0.60.2", @@ -510,7 +510,7 @@ dependencies = [ "serde-untagged", "serde-value", "thiserror 1.0.69", - "toml", + "toml 0.8.23", "unicode-xid", "url", ] @@ -527,7 +527,7 @@ dependencies = [ "serde_json", "snapbox", "thiserror 2.0.12", - "toml", + "toml 0.9.0", "unicode-xid", "url", ] @@ -3659,6 +3659,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +dependencies = [ + "serde", +] + [[package]] name = "sha1" version = "0.10.6" @@ -4039,9 +4048,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", +] + +[[package]] +name = "toml" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f271e09bde39ab52250160a67e88577e0559ad77e9085de6e9051a2c4353f8f8" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 1.0.0", + "toml_datetime 0.7.0", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] @@ -4053,6 +4077,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +dependencies = [ + "serde", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -4061,18 +4094,48 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_write", "winnow", ] +[[package]] +name = "toml_edit" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54449f7f7569ce6f57cda7812361961c0f6a77f720802537b5618585b4a7ff4c" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 1.0.0", + "toml_datetime 0.7.0", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5c1c469eda89749d2230d8156a5969a69ffe0d6d01200581cdc6110674d293e" +dependencies = [ + "winnow", +] + [[package]] name = "toml_write" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "toml_writer" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b679217f2848de74cabd3e8fc5e6d66f40b7da40f8e1954d92054d9010690fd5" + [[package]] name = "tracing" version = "0.1.41" @@ -4752,7 +4815,7 @@ dependencies = [ name = "xtask-stale-label" version = "0.0.0" dependencies = [ - "toml_edit", + "toml_edit 0.23.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 87dfc598b..ba81b29b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,8 +105,8 @@ tar = { version = "0.4.44", default-features = false } tempfile = "3.20.0" thiserror = "2.0.12" time = { version = "0.3.41", features = ["parsing", "formatting", "serde"] } -toml = { version = "0.8.23", default-features = false } -toml_edit = { version = "0.22.27", features = ["serde"] } +toml = { version = "0.9.0", default-features = false } +toml_edit = { version = "0.23.0", features = ["serde"] } tracing = { version = "0.1.41", default-features = false, features = ["std"] } # be compatible with rustc_log: https://github.com/rust-lang/rust/blob/e51e98dde6a/compiler/rustc_log/Cargo.toml#L9 tracing-chrome = "0.7.2" tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } @@ -211,7 +211,7 @@ tar.workspace = true tempfile.workspace = true thiserror.workspace = true time.workspace = true -toml = { workspace = true, features = ["display", "parse"] } +toml = { workspace = true, features = ["std", "serde", "parse", "display", "preserve_order"] } toml_edit.workspace = true tracing = { workspace = true, features = ["attributes"] } tracing-subscriber.workspace = true diff --git a/benches/capture/Cargo.toml b/benches/capture/Cargo.toml index 177892f9b..2a8466d2b 100644 --- a/benches/capture/Cargo.toml +++ b/benches/capture/Cargo.toml @@ -10,7 +10,7 @@ publish = false cargo_metadata.workspace = true flate2.workspace = true tar.workspace = true -toml = { workspace = true, features = ["display", "parse"] } +toml = { workspace = true, features = ["display", "parse", "serde"] } [lints] workspace = true diff --git a/crates/cargo-test-support/Cargo.toml b/crates/cargo-test-support/Cargo.toml index d37951a52..41a8f3101 100644 --- a/crates/cargo-test-support/Cargo.toml +++ b/crates/cargo-test-support/Cargo.toml @@ -27,7 +27,7 @@ serde_json.workspace = true snapbox.workspace = true tar.workspace = true time.workspace = true -toml = { workspace = true, features = ["display"] } +toml = { workspace = true, features = ["display", "serde"] } url.workspace = true walkdir.workspace = true diff --git a/crates/cargo-util-schemas/Cargo.toml b/crates/cargo-util-schemas/Cargo.toml index e45ee3386..4159e33c2 100644 --- a/crates/cargo-util-schemas/Cargo.toml +++ b/crates/cargo-util-schemas/Cargo.toml @@ -16,7 +16,7 @@ serde_json = { workspace = true, optional = true } serde-untagged.workspace = true serde-value.workspace = true thiserror.workspace = true -toml.workspace = true +toml = { workspace = true, features = ["serde"] } unicode-xid.workspace = true url.workspace = true diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 76e90f9f8..c9decda4d 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -63,7 +63,7 @@ impl EitherManifest { pub struct Manifest { // alternate forms of manifests: contents: Rc, - document: Rc>, + document: Rc>>, original_toml: Rc, normalized_toml: Rc, summary: Summary, @@ -109,7 +109,7 @@ pub struct Warnings(Vec); pub struct VirtualManifest { // alternate forms of manifests: contents: Rc, - document: Rc>, + document: Rc>>, original_toml: Rc, normalized_toml: Rc, @@ -496,7 +496,7 @@ compact_debug! { impl Manifest { pub fn new( contents: Rc, - document: Rc>, + document: Rc>>, original_toml: Rc, normalized_toml: Rc, summary: Summary, @@ -565,7 +565,7 @@ impl Manifest { Ok(format!("{}\n{}", MANIFEST_PREAMBLE, toml)) } /// Collection of spans for the original TOML - pub fn document(&self) -> &toml_edit::ImDocument { + pub fn document(&self) -> &toml::Spanned> { &self.document } /// The [`TomlManifest`] as parsed from [`Manifest::document`] @@ -738,7 +738,7 @@ impl Manifest { impl VirtualManifest { pub fn new( contents: Rc, - document: Rc>, + document: Rc>>, original_toml: Rc, normalized_toml: Rc, replace: Vec<(PackageIdSpec, Dependency)>, @@ -766,7 +766,7 @@ impl VirtualManifest { self.contents.as_str() } /// Collection of spans for the original TOML - pub fn document(&self) -> &toml_edit::ImDocument { + pub fn document(&self) -> &toml::Spanned> { &self.document } /// The [`TomlManifest`] as parsed from [`VirtualManifest::document`] diff --git a/src/cargo/util/context/mod.rs b/src/cargo/util/context/mod.rs index ef69f3886..731255800 100644 --- a/src/cargo/util/context/mod.rs +++ b/src/cargo/util/context/mod.rs @@ -1043,10 +1043,9 @@ impl GlobalContext { let def = Definition::Environment(key.as_env_key().to_string()); if self.cli_unstable().advanced_env && env_val.starts_with('[') && env_val.ends_with(']') { // Parse an environment string as a TOML array. - let toml_v = toml::Value::deserialize(toml::de::ValueDeserializer::new(&env_val)) - .map_err(|e| { - ConfigError::new(format!("could not parse TOML list: {}", e), def.clone()) - })?; + let toml_v = env_val.parse::().map_err(|e| { + ConfigError::new(format!("could not parse TOML list: {}", e), def.clone()) + })?; let values = toml_v.as_array().expect("env var was not array"); for value in values { // TODO: support other types. diff --git a/src/cargo/util/lints.rs b/src/cargo/util/lints.rs index 025384487..249d8b300 100644 --- a/src/cargo/util/lints.rs +++ b/src/cargo/util/lints.rs @@ -6,7 +6,6 @@ use pathdiff::diff_paths; use std::fmt::Display; use std::ops::Range; use std::path::Path; -use toml_edit::ImDocument; const LINT_GROUPS: &[LintGroup] = &[TEST_DUMMY_UNSTABLE]; pub const LINTS: &[Lint] = &[IM_A_TEAPOT, UNKNOWN_LINTS]; @@ -16,7 +15,7 @@ pub fn analyze_cargo_lints_table( path: &Path, pkg_lints: &TomlToolLints, ws_contents: &str, - ws_document: &ImDocument, + ws_document: &toml::Spanned>, ws_path: &Path, gctx: &GlobalContext, ) -> CargoResult<()> { @@ -116,7 +115,7 @@ fn verify_feature_enabled( manifest: &Manifest, manifest_path: &str, ws_contents: &str, - ws_document: &ImDocument, + ws_document: &toml::Spanned>, ws_path: &str, error_count: &mut usize, gctx: &GlobalContext, @@ -191,43 +190,33 @@ fn verify_feature_enabled( } pub fn get_span( - document: &ImDocument, + document: &toml::Spanned>, path: &[&str], get_value: bool, ) -> Option> { - let mut table = document.as_item().as_table_like()?; + let mut table = document.get_ref(); let mut iter = path.into_iter().peekable(); while let Some(key) = iter.next() { - let (key, item) = table.get_key_value(key)?; + let key_s: &str = key.as_ref(); + let (key, item) = table.get_key_value(key_s)?; if iter.peek().is_none() { return if get_value { - item.span() + Some(item.span()) } else { - let leaf_decor = key.dotted_decor(); - let leaf_prefix_span = leaf_decor.prefix().and_then(|p| p.span()); - let leaf_suffix_span = leaf_decor.suffix().and_then(|s| s.span()); - if let (Some(leaf_prefix_span), Some(leaf_suffix_span)) = - (leaf_prefix_span, leaf_suffix_span) - { - Some(leaf_prefix_span.start..leaf_suffix_span.end) - } else { - key.span() - } + Some(key.span()) }; } - if item.is_table_like() { - table = item.as_table_like().unwrap(); + if let Some(next_table) = item.get_ref().as_table() { + table = next_table; } - if item.is_array() && iter.peek().is_some() { - let array = item.as_array().unwrap(); - let next = iter.next().unwrap(); - return array.iter().find_map(|item| { - if next == &item.to_string() { - item.span() - } else { - None - } - }); + if iter.peek().is_some() { + if let Some(array) = item.get_ref().as_array() { + let next = iter.next().unwrap(); + return array.iter().find_map(|item| match item.get_ref() { + toml::de::DeValue::String(s) if s == next => Some(item.span()), + _ => None, + }); + } } } None @@ -511,7 +500,7 @@ fn output_unknown_lints( manifest_path: &str, pkg_lints: &TomlToolLints, ws_contents: &str, - ws_document: &ImDocument, + ws_document: &toml::Spanned>, ws_path: &str, error_count: &mut usize, gctx: &GlobalContext, diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 28f9ba738..3392bcba6 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -19,7 +19,6 @@ use cargo_util_schemas::manifest::{RustVersion, StringOrBool}; use itertools::Itertools; use lazycell::LazyCell; use pathdiff::diff_paths; -use toml_edit::ImDocument; use url::Url; use crate::core::compiler::{CompileKind, CompileTarget}; @@ -166,16 +165,28 @@ fn read_toml_string(path: &Path, is_embedded: bool, gctx: &GlobalContext) -> Car } #[tracing::instrument(skip_all)] -fn parse_document(contents: &str) -> Result, toml_edit::de::Error> { - toml_edit::ImDocument::parse(contents.to_owned()).map_err(Into::into) +fn parse_document( + contents: &str, +) -> Result>, toml::de::Error> { + let mut table = toml::de::DeTable::parse(contents)?; + table.get_mut().make_owned(); + // SAFETY: `DeTable::make_owned` ensures no borrows remain and the lifetime does not affect + // layout + let table = unsafe { + std::mem::transmute::< + toml::Spanned>, + toml::Spanned>, + >(table) + }; + Ok(table) } #[tracing::instrument(skip_all)] fn deserialize_toml( - document: &toml_edit::ImDocument, -) -> Result { + document: &toml::Spanned>, +) -> Result { let mut unused = BTreeSet::new(); - let deserializer = toml_edit::de::Deserializer::from(document.clone()); + let deserializer = toml::de::Deserializer::from(document.clone()); let mut document: manifest::TomlManifest = serde_ignored::deserialize(deserializer, |path| { let mut key = String::new(); stringify(&mut key, &path); @@ -1256,7 +1267,7 @@ fn deprecated_ws_default_features( #[tracing::instrument(skip_all)] pub fn to_real_manifest( contents: String, - document: toml_edit::ImDocument, + document: toml::Spanned>, original_toml: manifest::TomlManifest, normalized_toml: manifest::TomlManifest, features: Features, @@ -1843,7 +1854,7 @@ pub fn to_real_manifest( fn missing_dep_diagnostic( missing_dep: &MissingDependencyError, orig_toml: &TomlManifest, - document: &ImDocument, + document: &toml::Spanned>, contents: &str, manifest_file: &Path, gctx: &GlobalContext, @@ -1921,7 +1932,7 @@ fn missing_dep_diagnostic( fn to_virtual_manifest( contents: String, - document: toml_edit::ImDocument, + document: toml::Spanned>, original_toml: manifest::TomlManifest, normalized_toml: manifest::TomlManifest, features: Features, @@ -2761,7 +2772,7 @@ fn lints_to_rustflags(lints: &manifest::TomlLints) -> CargoResult> { } fn emit_diagnostic( - e: toml_edit::de::Error, + e: toml::de::Error, contents: &str, manifest_file: &Path, gctx: &GlobalContext, diff --git a/tests/testsuite/alt_registry.rs b/tests/testsuite/alt_registry.rs index 58ac1f101..7e3774bc6 100644 --- a/tests/testsuite/alt_registry.rs +++ b/tests/testsuite/alt_registry.rs @@ -751,13 +751,11 @@ fn bad_registry_name() { [ERROR] invalid character ` ` in registry name: `bad name`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters) - --> Cargo.toml:8:17 - | - 8 | / [dependencies.bar] - 9 | | version = "0.0.1" -10 | | registry = "bad name" - | |_____________________________________^ - | + --> Cargo.toml:8:17 + | +8 | [dependencies.bar] + | ^^^^^^^^^^^^^^^^^^ + | "#]]) .run(); diff --git a/tests/testsuite/bad_config.rs b/tests/testsuite/bad_config.rs index 4b94654a0..da7d47329 100644 --- a/tests/testsuite/bad_config.rs +++ b/tests/testsuite/bad_config.rs @@ -172,7 +172,7 @@ Caused by: | 1 | 4 | ^ - expected `.`, `=` + key with no value, expected `=` "#]]) .run(); @@ -454,8 +454,7 @@ fn malformed_override() { p.cargo("check") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] invalid inline table -expected `}` +[ERROR] newlines are unsupported in inline tables, expected nothing --> Cargo.toml:9:27 | 9 | native = { @@ -2130,8 +2129,7 @@ Caused by: | 1 | [bar] baz = 2 | ^ - invalid table header - expected newline, `#` + unexpected key or value, expected newline, `#` "#]]) .run(); diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 92b030e21..4c44c8836 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -377,11 +377,11 @@ Caused by: could not parse TOML configuration in `[ROOT]/foo/.cargo/config.toml` Caused by: - TOML parse error at line 1, column 1 + TOML parse error at line 1, column 2 | 1 | ! - | ^ - invalid key + | ^ + key with no value, expected `=` "#]]) .run(); @@ -418,12 +418,11 @@ fn cargo_compile_with_invalid_manifest2() { p.cargo("build") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] invalid string -expected `"`, `'` +[ERROR] string values must be quoted, expected literal string --> Cargo.toml:3:23 | 3 | foo = bar - | ^ + | ^^^ | "#]]) @@ -437,12 +436,11 @@ fn cargo_compile_with_invalid_manifest3() { p.cargo("build --manifest-path src/Cargo.toml") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] invalid string -expected `"`, `'` +[ERROR] string values must be quoted, expected literal string --> src/Cargo.toml:1:5 | 1 | a = bar - | ^ + | ^^^ | "#]]) @@ -2740,7 +2738,7 @@ Caused by: | 1 | this is not valid toml | ^ - expected `.`, `=` + key with no value, expected `=` "#]]) .run(); diff --git a/tests/testsuite/cargo_add/invalid_manifest/stderr.term.svg b/tests/testsuite/cargo_add/invalid_manifest/stderr.term.svg index 0ebf039fc..f9c867bc7 100644 --- a/tests/testsuite/cargo_add/invalid_manifest/stderr.term.svg +++ b/tests/testsuite/cargo_add/invalid_manifest/stderr.term.svg @@ -1,4 +1,4 @@ - +