@@ -7,6 +7,7 @@ use crate::core::{PackageId, PackageIdSpec, PackageIdSpecQuery};
7
7
use crate :: core:: { Resolve , SourceId , Workspace } ;
8
8
use crate :: ops;
9
9
use crate :: sources:: source:: QueryKind ;
10
+ use crate :: sources:: IndexSummary ;
10
11
use crate :: util:: cache_lock:: CacheLockMode ;
11
12
use crate :: util:: context:: GlobalContext ;
12
13
use crate :: util:: toml_mut:: dependency:: { MaybeWorkspace , Source } ;
@@ -15,6 +16,7 @@ use crate::util::toml_mut::upgrade::upgrade_requirement;
15
16
use crate :: util:: { style, OptVersionReq } ;
16
17
use crate :: util:: { CargoResult , VersionExt } ;
17
18
use anyhow:: Context as _;
19
+ use cargo_util_schemas:: core:: PartialVersion ;
18
20
use itertools:: Itertools ;
19
21
use semver:: { Op , Version , VersionReq } ;
20
22
use std:: cmp:: Ordering ;
@@ -498,10 +500,6 @@ fn print_lockfile_generation(
498
500
status_locking ( ws, num_pkgs) ?;
499
501
500
502
for diff in diff {
501
- fn format_latest ( version : semver:: Version ) -> String {
502
- let warn = style:: WARN ;
503
- format ! ( " {warn}(latest: v{version}){warn:#}" )
504
- }
505
503
let possibilities = if let Some ( query) = diff. alternatives_query ( ) {
506
504
loop {
507
505
match registry. query_vec ( & query, QueryKind :: Exact ) {
@@ -516,22 +514,14 @@ fn print_lockfile_generation(
516
514
} ;
517
515
518
516
for package in diff. added . iter ( ) {
519
- let latest = if !possibilities. is_empty ( ) {
520
- possibilities
521
- . iter ( )
522
- . map ( |s| s. as_summary ( ) )
523
- . filter ( |s| is_latest ( s. version ( ) , package. version ( ) ) )
524
- . map ( |s| s. version ( ) . clone ( ) )
525
- . max ( )
526
- . map ( format_latest)
527
- } else {
528
- None
529
- } ;
517
+ let required_rust_version = report_required_rust_version ( ws, resolve, * package) ;
518
+ let latest = report_latest ( & possibilities, * package) ;
519
+ let note = required_rust_version. or ( latest) ;
530
520
531
- if let Some ( latest ) = latest {
521
+ if let Some ( note ) = note {
532
522
ws. gctx ( ) . shell ( ) . status_with_color (
533
523
"Adding" ,
534
- format ! ( "{package}{latest }" ) ,
524
+ format ! ( "{package}{note }" ) ,
535
525
& style:: NOTE ,
536
526
) ?;
537
527
}
@@ -555,10 +545,6 @@ fn print_lockfile_sync(
555
545
status_locking ( ws, num_pkgs) ?;
556
546
557
547
for diff in diff {
558
- fn format_latest ( version : semver:: Version ) -> String {
559
- let warn = style:: WARN ;
560
- format ! ( " {warn}(latest: v{version}){warn:#}" )
561
- }
562
548
let possibilities = if let Some ( query) = diff. alternatives_query ( ) {
563
549
loop {
564
550
match registry. query_vec ( & query, QueryKind :: Exact ) {
@@ -610,22 +596,13 @@ fn print_lockfile_sync(
610
596
}
611
597
} else {
612
598
for package in diff. added . iter ( ) {
613
- let latest = if !possibilities. is_empty ( ) {
614
- possibilities
615
- . iter ( )
616
- . map ( |s| s. as_summary ( ) )
617
- . filter ( |s| is_latest ( s. version ( ) , package. version ( ) ) )
618
- . map ( |s| s. version ( ) . clone ( ) )
619
- . max ( )
620
- . map ( format_latest)
621
- } else {
622
- None
623
- }
624
- . unwrap_or_default ( ) ;
599
+ let required_rust_version = report_required_rust_version ( ws, resolve, * package) ;
600
+ let latest = report_latest ( & possibilities, * package) ;
601
+ let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
625
602
626
603
ws. gctx ( ) . shell ( ) . status_with_color (
627
604
"Adding" ,
628
- format ! ( "{package}{latest }" ) ,
605
+ format ! ( "{package}{note }" ) ,
629
606
& style:: NOTE ,
630
607
) ?;
631
608
}
@@ -650,10 +627,6 @@ fn print_lockfile_updates(
650
627
651
628
let mut unchanged_behind = 0 ;
652
629
for diff in diff {
653
- fn format_latest ( version : semver:: Version ) -> String {
654
- let warn = style:: WARN ;
655
- format ! ( " {warn}(latest: v{version}){warn:#}" )
656
- }
657
630
let possibilities = if let Some ( query) = diff. alternatives_query ( ) {
658
631
loop {
659
632
match registry. query_vec ( & query, QueryKind :: Exact ) {
@@ -668,26 +641,17 @@ fn print_lockfile_updates(
668
641
} ;
669
642
670
643
if let Some ( ( removed, added) ) = diff. change ( ) {
671
- let latest = if !possibilities. is_empty ( ) {
672
- possibilities
673
- . iter ( )
674
- . map ( |s| s. as_summary ( ) )
675
- . filter ( |s| is_latest ( s. version ( ) , added. version ( ) ) )
676
- . map ( |s| s. version ( ) . clone ( ) )
677
- . max ( )
678
- . map ( format_latest)
679
- } else {
680
- None
681
- }
682
- . unwrap_or_default ( ) ;
644
+ let required_rust_version = report_required_rust_version ( ws, resolve, * added) ;
645
+ let latest = report_latest ( & possibilities, * added) ;
646
+ let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
683
647
684
648
let msg = if removed. source_id ( ) . is_git ( ) {
685
649
format ! (
686
- "{removed} -> #{}" ,
650
+ "{removed} -> #{}{note} " ,
687
651
& added. source_id( ) . precise_git_fragment( ) . unwrap( ) [ ..8 ] ,
688
652
)
689
653
} else {
690
- format ! ( "{removed} -> v{}{latest }" , added. version( ) )
654
+ format ! ( "{removed} -> v{}{note }" , added. version( ) )
691
655
} ;
692
656
693
657
// If versions differ only in build metadata, we call it an "update"
@@ -712,45 +676,30 @@ fn print_lockfile_updates(
712
676
) ?;
713
677
}
714
678
for package in diff. added . iter ( ) {
715
- let latest = if !possibilities. is_empty ( ) {
716
- possibilities
717
- . iter ( )
718
- . map ( |s| s. as_summary ( ) )
719
- . filter ( |s| is_latest ( s. version ( ) , package. version ( ) ) )
720
- . map ( |s| s. version ( ) . clone ( ) )
721
- . max ( )
722
- . map ( format_latest)
723
- } else {
724
- None
725
- }
726
- . unwrap_or_default ( ) ;
679
+ let required_rust_version = report_required_rust_version ( ws, resolve, * package) ;
680
+ let latest = report_latest ( & possibilities, * package) ;
681
+ let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
727
682
728
683
ws. gctx ( ) . shell ( ) . status_with_color (
729
684
"Adding" ,
730
- format ! ( "{package}{latest }" ) ,
685
+ format ! ( "{package}{note }" ) ,
731
686
& style:: NOTE ,
732
687
) ?;
733
688
}
734
689
}
735
690
for package in & diff. unchanged {
736
- let latest = if !possibilities. is_empty ( ) {
737
- possibilities
738
- . iter ( )
739
- . map ( |s| s. as_summary ( ) )
740
- . filter ( |s| is_latest ( s. version ( ) , package. version ( ) ) )
741
- . map ( |s| s. version ( ) . clone ( ) )
742
- . max ( )
743
- . map ( format_latest)
744
- } else {
745
- None
746
- } ;
691
+ let required_rust_version = report_required_rust_version ( ws, resolve, * package) ;
692
+ let latest = report_latest ( & possibilities, * package) ;
693
+ let note = required_rust_version. as_deref ( ) . or ( latest. as_deref ( ) ) ;
747
694
748
- if let Some ( latest) = latest {
749
- unchanged_behind += 1 ;
695
+ if let Some ( note) = note {
696
+ if latest. is_some ( ) {
697
+ unchanged_behind += 1 ;
698
+ }
750
699
if ws. gctx ( ) . shell ( ) . verbosity ( ) == Verbosity :: Verbose {
751
700
ws. gctx ( ) . shell ( ) . status_with_color (
752
701
"Unchanged" ,
753
- format ! ( "{package}{latest }" ) ,
702
+ format ! ( "{package}{note }" ) ,
754
703
& anstyle:: Style :: new ( ) . bold ( ) ,
755
704
) ?;
756
705
}
@@ -788,14 +737,7 @@ fn status_locking(ws: &Workspace<'_>, num_pkgs: usize) -> CargoResult<()> {
788
737
write ! ( & mut cfg, " latest" ) ?;
789
738
}
790
739
791
- if ws. resolve_honors_rust_version ( ) {
792
- let rust_version = if let Some ( ver) = ws. rust_version ( ) {
793
- ver. clone ( ) . into_partial ( )
794
- } else {
795
- let rustc = ws. gctx ( ) . load_global_rustc ( Some ( ws) ) ?;
796
- let rustc_version = rustc. version . clone ( ) . into ( ) ;
797
- rustc_version
798
- } ;
740
+ if let Some ( rust_version) = required_rust_version ( ws) {
799
741
write ! ( & mut cfg, " Rust {rust_version}" ) ?;
800
742
}
801
743
write ! ( & mut cfg, " compatible version{plural}" ) ?;
@@ -807,6 +749,60 @@ fn status_locking(ws: &Workspace<'_>, num_pkgs: usize) -> CargoResult<()> {
807
749
Ok ( ( ) )
808
750
}
809
751
752
+ fn required_rust_version ( ws : & Workspace < ' _ > ) -> Option < PartialVersion > {
753
+ if !ws. resolve_honors_rust_version ( ) {
754
+ return None ;
755
+ }
756
+
757
+ if let Some ( ver) = ws. rust_version ( ) {
758
+ Some ( ver. clone ( ) . into_partial ( ) )
759
+ } else {
760
+ let rustc = ws. gctx ( ) . load_global_rustc ( Some ( ws) ) . ok ( ) ?;
761
+ let rustc_version = rustc. version . clone ( ) . into ( ) ;
762
+ Some ( rustc_version)
763
+ }
764
+ }
765
+
766
+ fn report_required_rust_version (
767
+ ws : & Workspace < ' _ > ,
768
+ resolve : & Resolve ,
769
+ package : PackageId ,
770
+ ) -> Option < String > {
771
+ if package. source_id ( ) . is_path ( ) {
772
+ return None ;
773
+ }
774
+ let summary = resolve. summary ( package) ;
775
+ let package_rust_version = summary. rust_version ( ) ?;
776
+ let workspace_rust_version = required_rust_version ( ws) ?;
777
+ if package_rust_version. is_compatible_with ( & workspace_rust_version) {
778
+ return None ;
779
+ }
780
+
781
+ let warn = style:: WARN ;
782
+ Some ( format ! (
783
+ " {warn}(requires Rust {package_rust_version}){warn:#}"
784
+ ) )
785
+ }
786
+
787
+ fn report_latest ( possibilities : & [ IndexSummary ] , package : PackageId ) -> Option < String > {
788
+ if !package. source_id ( ) . is_registry ( ) {
789
+ return None ;
790
+ }
791
+
792
+ possibilities
793
+ . iter ( )
794
+ . map ( |s| s. as_summary ( ) )
795
+ . filter ( |s| is_latest ( s. version ( ) , package. version ( ) ) )
796
+ . map ( |s| s. version ( ) . clone ( ) )
797
+ . max ( )
798
+ . map ( format_latest)
799
+ }
800
+
801
+ fn format_latest ( version : semver:: Version ) -> String {
802
+ let warn = style:: WARN ;
803
+ format ! ( " {warn}(latest: v{version}){warn:#}" )
804
+ }
805
+
810
806
fn is_latest ( candidate : & semver:: Version , current : & semver:: Version ) -> bool {
811
807
current < candidate
812
808
// Only match pre-release if major.minor.patch are the same
0 commit comments