@@ -20,6 +20,7 @@ use toml_edit::Item as TomlItem;
20
20
21
21
use crate :: CargoResult ;
22
22
use crate :: GlobalContext ;
23
+ use crate :: core:: Feature ;
23
24
use crate :: core:: FeatureValue ;
24
25
use crate :: core:: Features ;
25
26
use crate :: core:: Package ;
@@ -29,6 +30,7 @@ use crate::core::Summary;
29
30
use crate :: core:: Workspace ;
30
31
use crate :: core:: dependency:: DepKind ;
31
32
use crate :: core:: registry:: PackageRegistry ;
33
+ use crate :: ops:: resolve_ws;
32
34
use crate :: sources:: source:: QueryKind ;
33
35
use crate :: util:: cache_lock:: CacheLockMode ;
34
36
use crate :: util:: edit_distance;
@@ -38,6 +40,7 @@ use crate::util::toml_mut::dependency::Dependency;
38
40
use crate :: util:: toml_mut:: dependency:: GitSource ;
39
41
use crate :: util:: toml_mut:: dependency:: MaybeWorkspace ;
40
42
use crate :: util:: toml_mut:: dependency:: PathSource ;
43
+ use crate :: util:: toml_mut:: dependency:: RegistrySource ;
41
44
use crate :: util:: toml_mut:: dependency:: Source ;
42
45
use crate :: util:: toml_mut:: dependency:: WorkspaceSource ;
43
46
use crate :: util:: toml_mut:: manifest:: DepTable ;
@@ -472,17 +475,44 @@ fn resolve_dependency(
472
475
}
473
476
dependency = dependency. set_source ( src) ;
474
477
} 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" ) ) ;
484
515
}
485
- dependency = dependency. set_source ( latest. source . expect ( "latest always has a source" ) ) ;
486
516
}
487
517
}
488
518
@@ -501,6 +531,89 @@ fn resolve_dependency(
501
531
dependency = dependency. clear_version ( ) ;
502
532
}
503
533
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 > {
504
617
let query = dependency. query ( gctx) ?;
505
618
let query = match query {
506
619
MaybeWorkspace :: Workspace ( _workspace) => {
@@ -511,7 +624,7 @@ fn resolve_dependency(
511
624
ws. unstable_features ( ) ,
512
625
) ?;
513
626
if let Some ( features) = dep. features . clone ( ) {
514
- dependency = dependency. set_inherited_features ( features) ;
627
+ * dependency = dependency. clone ( ) . set_inherited_features ( features) ;
515
628
}
516
629
let query = dep. query ( gctx) ?;
517
630
match query {
@@ -523,10 +636,7 @@ fn resolve_dependency(
523
636
}
524
637
MaybeWorkspace :: Other ( query) => query,
525
638
} ;
526
-
527
- let dependency = populate_available_features ( dependency, & query, registry) ?;
528
-
529
- Ok ( dependency)
639
+ Ok ( query)
530
640
}
531
641
532
642
fn fuzzy_lookup (
0 commit comments