Skip to content

Commit 9c83284

Browse files
committed
Search dep in other tables
Signed-off-by: hi-rustin <rustin.liu@gmail.com>
1 parent 7f3fc2b commit 9c83284

File tree

1 file changed

+72
-12
lines changed

1 file changed

+72
-12
lines changed

src/cargo/util/toml_mut/manifest.rs

+72-12
Original file line numberDiff line numberDiff line change
@@ -367,22 +367,77 @@ impl LocalManifest {
367367
pub fn remove_from_table(&mut self, table_path: &[String], name: &str) -> CargoResult<()> {
368368
let parent_table = self.get_table_mut(table_path)?;
369369

370-
let dep = parent_table
371-
.get_mut(name)
372-
.filter(|t| !t.is_none())
373-
.ok_or_else(|| non_existent_dependency_err(name, table_path.join(".")))?;
374-
375-
// remove the dependency
376-
*dep = toml_edit::Item::None;
370+
match parent_table.get_mut(name).filter(|t| !t.is_none()) {
371+
Some(dep) => {
372+
// remove the dependency
373+
*dep = toml_edit::Item::None;
374+
375+
// remove table if empty
376+
if parent_table.as_table_like().unwrap().is_empty() {
377+
*parent_table = toml_edit::Item::None;
378+
}
379+
}
380+
None => {
381+
// Search in other tables.
382+
let table_paths = self.get_all_deps_table_paths();
383+
let found_table_path = table_paths
384+
.iter()
385+
.find(|table_path| {
386+
let table = self.get_table(table_path).unwrap();
387+
table.get(name).filter(|t| !t.is_none()).is_some()
388+
})
389+
.map(|table_path| table_path.join("."));
377390

378-
// remove table if empty
379-
if parent_table.as_table_like().unwrap().is_empty() {
380-
*parent_table = toml_edit::Item::None;
391+
return Err(non_existent_dependency_err(
392+
name,
393+
table_path.join("."),
394+
found_table_path,
395+
));
396+
}
381397
}
382398

383399
Ok(())
384400
}
385401

402+
fn get_all_deps_table_paths(&self) -> Vec<Vec<String>> {
403+
let mut result = Vec::new();
404+
405+
for table in DepTable::KINDS {
406+
let dependency_type = table.kind.kind_table();
407+
// Dependencies can be in the three standard sections...
408+
if self
409+
.data
410+
.get(dependency_type)
411+
.map(|t| t.is_table_like())
412+
.unwrap_or(false)
413+
{
414+
result.push(vec![dependency_type.to_owned()])
415+
}
416+
417+
// And in `target.<target>.(build-/dev-)dependencies`.
418+
result.extend(
419+
self.data
420+
.as_table()
421+
.get("target")
422+
.and_then(toml_edit::Item::as_table_like)
423+
.into_iter()
424+
.flat_map(toml_edit::TableLike::iter)
425+
.filter_map(|(target_name, target_table)| {
426+
let dependency_table = target_table.get(dependency_type)?;
427+
dependency_table.as_table_like().map(|_| {
428+
vec![
429+
"target".to_owned(),
430+
target_name.to_owned(),
431+
dependency_type.to_owned(),
432+
]
433+
})
434+
}),
435+
);
436+
}
437+
438+
result
439+
}
440+
386441
/// Remove references to `dep_key` if its no longer present.
387442
pub fn gc_dep(&mut self, dep_key: &str) {
388443
let explicit_dep_activation = self.is_explicit_dep_activation(dep_key);
@@ -537,9 +592,14 @@ fn non_existent_table_err(table: impl std::fmt::Display) -> anyhow::Error {
537592

538593
fn non_existent_dependency_err(
539594
name: impl std::fmt::Display,
540-
table: impl std::fmt::Display,
595+
search_table: impl std::fmt::Display,
596+
found_table: Option<impl std::fmt::Display>,
541597
) -> anyhow::Error {
542-
anyhow::format_err!("the dependency `{name}` could not be found in `{table}`.")
598+
let mut msg = format!("the dependency `{name}` could not be found in `{search_table}`.");
599+
if let Some(found_table) = found_table {
600+
msg.push_str(&format!("But it was found in `{found_table}`.",));
601+
}
602+
anyhow::format_err!(msg)
543603
}
544604

545605
fn remove_array_index(array: &mut toml_edit::Array, index: usize) {

0 commit comments

Comments
 (0)