From ad8fb2f0c9216f27bf3a63fe63f2d30776b2ffc2 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 8 Jul 2025 13:01:29 -0500 Subject: [PATCH] refactor(manifest): Switch from toml_edit to toml Technically this will cause a small regression in performance from `toml_edit@0.23` but not `toml_edit@0.22` --- src/cargo/core/manifest.rs | 12 +++++----- src/cargo/util/lints.rs | 49 +++++++++++++++----------------------- src/cargo/util/toml/mod.rs | 31 ++++++++++++++++-------- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 23a2cf9b0..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::Document { + 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::Document { + pub fn document(&self) -> &toml::Spanned> { &self.document } /// The [`TomlManifest`] as parsed from [`VirtualManifest::document`] diff --git a/src/cargo/util/lints.rs b/src/cargo/util/lints.rs index 9fac19bc7..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::Document; 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: &Document, + 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: &Document, + 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: &Document, + 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: &Document, + 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 da6a51550..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::Document; 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::Document::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::Document, -) -> 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::Document, + 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: &Document, + 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::Document, + 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,