@@ -20,6 +20,7 @@ use toml_edit::Item as TomlItem;
2020
2121use crate :: CargoResult ;
2222use crate :: GlobalContext ;
23+ use crate :: core:: Feature ;
2324use crate :: core:: FeatureValue ;
2425use crate :: core:: Features ;
2526use crate :: core:: Package ;
@@ -29,6 +30,7 @@ use crate::core::Summary;
2930use crate :: core:: Workspace ;
3031use crate :: core:: dependency:: DepKind ;
3132use crate :: core:: registry:: PackageRegistry ;
33+ use crate :: ops:: resolve_ws;
3234use crate :: sources:: source:: QueryKind ;
3335use crate :: util:: cache_lock:: CacheLockMode ;
3436use crate :: util:: edit_distance;
@@ -38,6 +40,7 @@ use crate::util::toml_mut::dependency::Dependency;
3840use crate :: util:: toml_mut:: dependency:: GitSource ;
3941use crate :: util:: toml_mut:: dependency:: MaybeWorkspace ;
4042use crate :: util:: toml_mut:: dependency:: PathSource ;
43+ use crate :: util:: toml_mut:: dependency:: RegistrySource ;
4144use crate :: util:: toml_mut:: dependency:: Source ;
4245use crate :: util:: toml_mut:: dependency:: WorkspaceSource ;
4346use crate :: util:: toml_mut:: manifest:: DepTable ;
@@ -472,17 +475,44 @@ fn resolve_dependency(
472475 }
473476 dependency = dependency. set_source ( src) ;
474477 } else {
475- let latest =
476- get_latest_dependency ( spec, & dependency, honor_rust_version, gctx, registry) ?;
477-
478- if dependency. name != latest. name {
479- gctx. shell ( ) . warn ( format ! (
480- "translating `{}` to `{}`" ,
481- dependency. name, latest. name,
482- ) ) ?;
483- dependency. name = latest. name ; // Normalize the name
478+ let ( package_set, resolve) = resolve_ws ( ws, true ) ?;
479+ let public_source = if spec
480+ . manifest ( )
481+ . unstable_features ( )
482+ . require ( Feature :: public_dependency ( ) )
483+ . is_ok ( )
484+ {
485+ get_public_dependency (
486+ manifest,
487+ ws,
488+ section,
489+ gctx,
490+ & dependency,
491+ package_set,
492+ resolve,
493+ )
494+ } else {
495+ None
496+ } ;
497+ if let Some ( ( registry, public_source) ) = public_source {
498+ if let Some ( registry) = registry {
499+ dependency = dependency. set_registry ( registry) ;
500+ }
501+ dependency = dependency. set_source ( public_source) ;
502+ } else {
503+ let latest =
504+ get_latest_dependency ( spec, & dependency, honor_rust_version, gctx, registry) ?;
505+
506+ if dependency. name != latest. name {
507+ gctx. shell ( ) . warn ( format ! (
508+ "translating `{}` to `{}`" ,
509+ dependency. name, latest. name,
510+ ) ) ?;
511+ dependency. name = latest. name ; // Normalize the name
512+ }
513+ dependency =
514+ dependency. set_source ( latest. source . expect ( "latest always has a source" ) ) ;
484515 }
485- dependency = dependency. set_source ( latest. source . expect ( "latest always has a source" ) ) ;
486516 }
487517 }
488518
@@ -501,6 +531,89 @@ fn resolve_dependency(
501531 dependency = dependency. clear_version ( ) ;
502532 }
503533
534+ let query = query_dependency ( ws, gctx, & mut dependency) ?;
535+ let dependency = populate_available_features ( dependency, & query, registry) ?;
536+
537+ Ok ( dependency)
538+ }
539+
540+ fn get_public_dependency (
541+ manifest : & LocalManifest ,
542+ ws : & Workspace < ' _ > ,
543+ section : & DepTable ,
544+ gctx : & GlobalContext ,
545+ dependency : & Dependency ,
546+ package_set : crate :: core:: PackageSet < ' _ > ,
547+ resolve : crate :: core:: Resolve ,
548+ ) -> Option < ( Option < String > , Source ) > {
549+ manifest
550+ . get_dependency_versions_all ( ws, ws. unstable_features ( ) )
551+ . filter_map ( |( path, dep) | if path == * section { dep. ok ( ) } else { None } )
552+ . filter_map ( |mut dep| {
553+ query_dependency ( ws, gctx, & mut dep)
554+ . map ( |dep| {
555+ package_set
556+ . package_ids ( )
557+ . filter ( |package_id| {
558+ package_id. name ( ) == dep. package_name ( )
559+ && dep. version_req ( ) . matches ( package_id. version ( ) )
560+ } )
561+ . max_by_key ( |x| x. version ( ) )
562+ } )
563+ . transpose ( )
564+ } )
565+ . map ( |dep_pkgid| {
566+ let Ok ( dep_pkgid) = dep_pkgid else {
567+ todo ! ( ) ;
568+ } ;
569+ resolve. deps ( dep_pkgid) . filter_map ( |( id, deps) | {
570+ deps. iter ( )
571+ . find ( |dep| {
572+ dep. is_public ( )
573+ && dep. kind ( ) == DepKind :: Normal
574+ && dep. package_name ( ) == dependency. name . as_str ( )
575+ } )
576+ . map ( |dep| ( id, dep. version_req ( ) . clone ( ) ) )
577+ } )
578+ } )
579+ . flatten ( )
580+ . max_by_key ( |( pkg_id, _) | pkg_id. version ( ) )
581+ . map ( |( pkg_id, version_req) | {
582+ let source = pkg_id. source_id ( ) ;
583+ if source. is_git ( ) {
584+ (
585+ Option :: < String > :: None ,
586+ Source :: Git ( GitSource :: new ( source. as_encoded_url ( ) . to_string ( ) ) ) ,
587+ )
588+ } else if let Some ( path) = source. local_path ( ) {
589+ ( None , Source :: Path ( PathSource :: new ( path) ) )
590+ } else {
591+ let toml_source = match version_req {
592+ crate :: util:: OptVersionReq :: Any => Source :: Registry ( RegistrySource :: new (
593+ format ! ( "={}" , pkg_id. version( ) . to_string( ) ) ,
594+ ) ) ,
595+ crate :: util:: OptVersionReq :: Req ( version_req)
596+ | crate :: util:: OptVersionReq :: Locked ( _, version_req)
597+ | crate :: util:: OptVersionReq :: Precise ( _, version_req) => {
598+ Source :: Registry ( RegistrySource :: new ( version_req. to_string ( ) ) )
599+ }
600+ } ;
601+ (
602+ source
603+ . alt_registry_key ( )
604+ . map ( |x| x. to_owned ( ) )
605+ . filter ( |_| !source. is_crates_io ( ) ) ,
606+ toml_source,
607+ )
608+ }
609+ } )
610+ }
611+
612+ fn query_dependency (
613+ ws : & Workspace < ' _ > ,
614+ gctx : & GlobalContext ,
615+ dependency : & mut Dependency ,
616+ ) -> CargoResult < crate :: core:: Dependency > {
504617 let query = dependency. query ( gctx) ?;
505618 let query = match query {
506619 MaybeWorkspace :: Workspace ( _workspace) => {
@@ -511,7 +624,7 @@ fn resolve_dependency(
511624 ws. unstable_features ( ) ,
512625 ) ?;
513626 if let Some ( features) = dep. features . clone ( ) {
514- dependency = dependency. set_inherited_features ( features) ;
627+ * dependency = dependency. clone ( ) . set_inherited_features ( features) ;
515628 }
516629 let query = dep. query ( gctx) ?;
517630 match query {
@@ -523,10 +636,7 @@ fn resolve_dependency(
523636 }
524637 MaybeWorkspace :: Other ( query) => query,
525638 } ;
526-
527- let dependency = populate_available_features ( dependency, & query, registry) ?;
528-
529- Ok ( dependency)
639+ Ok ( query)
530640}
531641
532642fn fuzzy_lookup (
0 commit comments