@@ -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
538593fn 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
545605fn remove_array_index ( array : & mut toml_edit:: Array , index : usize ) {
0 commit comments