@@ -492,18 +492,19 @@ fn print_lockfile_generation(
492
492
resolve : & Resolve ,
493
493
registry : & mut PackageRegistry < ' _ > ,
494
494
) -> CargoResult < ( ) > {
495
- let changes = PackageChange :: new ( ws, resolve) ;
495
+ let mut changes = PackageChange :: new ( ws, resolve) ;
496
496
let num_pkgs: usize = changes
497
- . iter ( )
497
+ . values ( )
498
498
. filter ( |change| change. kind . is_new ( ) && !change. is_member . unwrap_or ( false ) )
499
499
. count ( ) ;
500
500
if num_pkgs == 0 {
501
501
// nothing worth reporting
502
502
return Ok ( ( ) ) ;
503
503
}
504
- status_locking ( ws, num_pkgs ) ? ;
504
+ annotate_required_rust_version ( ws, resolve , & mut changes ) ;
505
505
506
- for change in changes {
506
+ status_locking ( ws, num_pkgs) ?;
507
+ for change in changes. values ( ) {
507
508
if change. is_member . unwrap_or ( false ) {
508
509
continue ;
509
510
} ;
@@ -523,7 +524,7 @@ fn print_lockfile_generation(
523
524
} ;
524
525
525
526
let package_id = change. package_id ;
526
- let required_rust_version = report_required_rust_version ( ws , resolve, package_id ) ;
527
+ let required_rust_version = report_required_rust_version ( resolve, change ) ;
527
528
let latest = report_latest ( & possibilities, package_id) ;
528
529
let note = required_rust_version. or ( latest) ;
529
530
@@ -553,18 +554,19 @@ fn print_lockfile_sync(
553
554
resolve : & Resolve ,
554
555
registry : & mut PackageRegistry < ' _ > ,
555
556
) -> CargoResult < ( ) > {
556
- let changes = PackageChange :: diff ( ws, previous_resolve, resolve) ;
557
+ let mut changes = PackageChange :: diff ( ws, previous_resolve, resolve) ;
557
558
let num_pkgs: usize = changes
558
- . iter ( )
559
+ . values ( )
559
560
. filter ( |change| change. kind . is_new ( ) && !change. is_member . unwrap_or ( false ) )
560
561
. count ( ) ;
561
562
if num_pkgs == 0 {
562
563
// nothing worth reporting
563
564
return Ok ( ( ) ) ;
564
565
}
565
- status_locking ( ws, num_pkgs ) ? ;
566
+ annotate_required_rust_version ( ws, resolve , & mut changes ) ;
566
567
567
- for change in changes {
568
+ status_locking ( ws, num_pkgs) ?;
569
+ for change in changes. values ( ) {
568
570
if change. is_member . unwrap_or ( false ) {
569
571
continue ;
570
572
} ;
@@ -586,7 +588,7 @@ fn print_lockfile_sync(
586
588
} ;
587
589
588
590
let package_id = change. package_id ;
589
- let required_rust_version = report_required_rust_version ( ws , resolve, package_id ) ;
591
+ let required_rust_version = report_required_rust_version ( resolve, change ) ;
590
592
let latest = report_latest ( & possibilities, package_id) ;
591
593
let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
592
594
@@ -610,14 +612,18 @@ fn print_lockfile_updates(
610
612
precise : bool ,
611
613
registry : & mut PackageRegistry < ' _ > ,
612
614
) -> CargoResult < ( ) > {
613
- let changes = PackageChange :: diff ( ws, previous_resolve, resolve) ;
614
- let num_pkgs: usize = changes. iter ( ) . filter ( |change| change. kind . is_new ( ) ) . count ( ) ;
615
+ let mut changes = PackageChange :: diff ( ws, previous_resolve, resolve) ;
616
+ let num_pkgs: usize = changes
617
+ . values ( )
618
+ . filter ( |change| change. kind . is_new ( ) )
619
+ . count ( ) ;
620
+ annotate_required_rust_version ( ws, resolve, & mut changes) ;
621
+
615
622
if !precise {
616
623
status_locking ( ws, num_pkgs) ?;
617
624
}
618
-
619
625
let mut unchanged_behind = 0 ;
620
- for change in changes {
626
+ for change in changes. values ( ) {
621
627
let possibilities = if let Some ( query) = change. alternatives_query ( ) {
622
628
loop {
623
629
match registry. query_vec ( & query, QueryKind :: Exact ) {
@@ -636,7 +642,7 @@ fn print_lockfile_updates(
636
642
| PackageChangeKind :: Upgraded
637
643
| PackageChangeKind :: Downgraded => {
638
644
let package_id = change. package_id ;
639
- let required_rust_version = report_required_rust_version ( ws , resolve, package_id ) ;
645
+ let required_rust_version = report_required_rust_version ( resolve, change ) ;
640
646
let latest = report_latest ( & possibilities, package_id) ;
641
647
let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
642
648
@@ -655,7 +661,7 @@ fn print_lockfile_updates(
655
661
}
656
662
PackageChangeKind :: Unchanged => {
657
663
let package_id = change. package_id ;
658
- let required_rust_version = report_required_rust_version ( ws , resolve, package_id ) ;
664
+ let required_rust_version = report_required_rust_version ( resolve, change ) ;
659
665
let latest = report_latest ( & possibilities, package_id) ;
660
666
let note = required_rust_version. as_deref ( ) . or ( latest. as_deref ( ) ) ;
661
667
@@ -731,24 +737,20 @@ fn required_rust_version(ws: &Workspace<'_>) -> Option<PartialVersion> {
731
737
}
732
738
}
733
739
734
- fn report_required_rust_version (
735
- ws : & Workspace < ' _ > ,
736
- resolve : & Resolve ,
737
- package : PackageId ,
738
- ) -> Option < String > {
739
- if package. source_id ( ) . is_path ( ) {
740
+ fn report_required_rust_version ( resolve : & Resolve , change : & PackageChange ) -> Option < String > {
741
+ if change. package_id . source_id ( ) . is_path ( ) {
740
742
return None ;
741
743
}
742
- let summary = resolve. summary ( package ) ;
744
+ let summary = resolve. summary ( change . package_id ) ;
743
745
let package_rust_version = summary. rust_version ( ) ?;
744
- let workspace_rust_version = required_rust_version ( ws ) ?;
745
- if package_rust_version. is_compatible_with ( & workspace_rust_version ) {
746
+ let required_rust_version = change . required_rust_version . as_ref ( ) ?;
747
+ if package_rust_version. is_compatible_with ( required_rust_version ) {
746
748
return None ;
747
749
}
748
750
749
- let warn = style:: WARN ;
751
+ let error = style:: ERROR ;
750
752
Some ( format ! (
751
- " {warn }(requires Rust {package_rust_version}){warn :#}"
753
+ " {error }(requires Rust {package_rust_version}){error :#}"
752
754
) )
753
755
}
754
756
@@ -801,20 +803,28 @@ struct PackageChange {
801
803
previous_id : Option < PackageId > ,
802
804
kind : PackageChangeKind ,
803
805
is_member : Option < bool > ,
806
+ required_rust_version : Option < PartialVersion > ,
804
807
}
805
808
806
809
impl PackageChange {
807
- pub fn new ( ws : & Workspace < ' _ > , resolve : & Resolve ) -> Vec < Self > {
810
+ pub fn new ( ws : & Workspace < ' _ > , resolve : & Resolve ) -> IndexMap < PackageId , Self > {
808
811
let diff = PackageDiff :: new ( resolve) ;
809
812
Self :: with_diff ( diff, ws)
810
813
}
811
814
812
- pub fn diff ( ws : & Workspace < ' _ > , previous_resolve : & Resolve , resolve : & Resolve ) -> Vec < Self > {
815
+ pub fn diff (
816
+ ws : & Workspace < ' _ > ,
817
+ previous_resolve : & Resolve ,
818
+ resolve : & Resolve ,
819
+ ) -> IndexMap < PackageId , Self > {
813
820
let diff = PackageDiff :: diff ( previous_resolve, resolve) ;
814
821
Self :: with_diff ( diff, ws)
815
822
}
816
823
817
- fn with_diff ( diff : impl Iterator < Item = PackageDiff > , ws : & Workspace < ' _ > ) -> Vec < Self > {
824
+ fn with_diff (
825
+ diff : impl Iterator < Item = PackageDiff > ,
826
+ ws : & Workspace < ' _ > ,
827
+ ) -> IndexMap < PackageId , Self > {
818
828
let member_ids: HashSet < _ > = ws. members ( ) . map ( |p| p. package_id ( ) ) . collect ( ) ;
819
829
820
830
let mut changes = IndexMap :: new ( ) ;
@@ -837,6 +847,7 @@ impl PackageChange {
837
847
previous_id : Some ( previous_id) ,
838
848
kind,
839
849
is_member,
850
+ required_rust_version : None ,
840
851
} ;
841
852
changes. insert ( change. package_id , change) ;
842
853
} else {
@@ -848,6 +859,7 @@ impl PackageChange {
848
859
previous_id : None ,
849
860
kind,
850
861
is_member,
862
+ required_rust_version : None ,
851
863
} ;
852
864
changes. insert ( change. package_id , change) ;
853
865
}
@@ -859,6 +871,7 @@ impl PackageChange {
859
871
previous_id : None ,
860
872
kind,
861
873
is_member,
874
+ required_rust_version : None ,
862
875
} ;
863
876
changes. insert ( change. package_id , change) ;
864
877
}
@@ -871,12 +884,13 @@ impl PackageChange {
871
884
previous_id : None ,
872
885
kind,
873
886
is_member,
887
+ required_rust_version : None ,
874
888
} ;
875
889
changes. insert ( change. package_id , change) ;
876
890
}
877
891
}
878
892
879
- changes. into_values ( ) . collect ( )
893
+ changes
880
894
}
881
895
882
896
/// For querying [`PackageRegistry`] for alternative versions to report to the user
@@ -1066,3 +1080,46 @@ impl PackageDiff {
1066
1080
}
1067
1081
}
1068
1082
}
1083
+
1084
+ fn annotate_required_rust_version (
1085
+ ws : & Workspace < ' _ > ,
1086
+ resolve : & Resolve ,
1087
+ changes : & mut IndexMap < PackageId , PackageChange > ,
1088
+ ) {
1089
+ let rustc = ws. gctx ( ) . load_global_rustc ( Some ( ws) ) . ok ( ) ;
1090
+ let rustc_version: Option < PartialVersion > =
1091
+ rustc. as_ref ( ) . map ( |rustc| rustc. version . clone ( ) . into ( ) ) ;
1092
+
1093
+ if ws. resolve_honors_rust_version ( ) {
1094
+ let mut queue: std:: collections:: VecDeque < _ > = ws
1095
+ . members ( )
1096
+ . map ( |p| {
1097
+ (
1098
+ p. rust_version ( )
1099
+ . map ( |r| r. clone ( ) . into_partial ( ) )
1100
+ . or_else ( || rustc_version. clone ( ) ) ,
1101
+ p. package_id ( ) ,
1102
+ )
1103
+ } )
1104
+ . collect ( ) ;
1105
+ while let Some ( ( required_rust_version, current_id) ) = queue. pop_front ( ) {
1106
+ let Some ( required_rust_version) = required_rust_version else {
1107
+ continue ;
1108
+ } ;
1109
+ if let Some ( change) = changes. get_mut ( & current_id) {
1110
+ if let Some ( existing) = change. required_rust_version . as_ref ( ) {
1111
+ if * existing <= required_rust_version {
1112
+ // Stop early; we already walked down this path with a better match
1113
+ continue ;
1114
+ }
1115
+ }
1116
+ change. required_rust_version = Some ( required_rust_version. clone ( ) ) ;
1117
+ }
1118
+ queue. extend (
1119
+ resolve
1120
+ . deps ( current_id)
1121
+ . map ( |( dep, _) | ( Some ( required_rust_version. clone ( ) ) , dep) ) ,
1122
+ ) ;
1123
+ }
1124
+ }
1125
+ }
0 commit comments