@@ -492,7 +492,7 @@ fn print_lockfile_generation(
492492 resolve : & Resolve ,
493493 registry : & mut PackageRegistry < ' _ > ,
494494) -> CargoResult < ( ) > {
495- let changes = PackageChange :: new ( ws, resolve) ;
495+ let mut changes = PackageChange :: new ( ws, resolve) ;
496496 let num_pkgs: usize = changes
497497 . values ( )
498498 . filter ( |change| change. kind . is_new ( ) && !change. is_member . unwrap_or ( false ) )
@@ -501,8 +501,9 @@ fn print_lockfile_generation(
501501 // nothing worth reporting
502502 return Ok ( ( ) ) ;
503503 }
504- status_locking ( ws, num_pkgs ) ? ;
504+ annotate_required_rust_version ( ws, resolve , & mut changes ) ;
505505
506+ status_locking ( ws, num_pkgs) ?;
506507 for change in changes. values ( ) {
507508 if change. is_member . unwrap_or ( false ) {
508509 continue ;
@@ -523,7 +524,7 @@ fn print_lockfile_generation(
523524 } ;
524525
525526 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 ) ;
527528 let latest = report_latest ( & possibilities, package_id) ;
528529 let note = required_rust_version. or ( latest) ;
529530
@@ -553,7 +554,7 @@ fn print_lockfile_sync(
553554 resolve : & Resolve ,
554555 registry : & mut PackageRegistry < ' _ > ,
555556) -> CargoResult < ( ) > {
556- let changes = PackageChange :: diff ( ws, previous_resolve, resolve) ;
557+ let mut changes = PackageChange :: diff ( ws, previous_resolve, resolve) ;
557558 let num_pkgs: usize = changes
558559 . values ( )
559560 . filter ( |change| change. kind . is_new ( ) && !change. is_member . unwrap_or ( false ) )
@@ -562,8 +563,9 @@ fn print_lockfile_sync(
562563 // nothing worth reporting
563564 return Ok ( ( ) ) ;
564565 }
565- status_locking ( ws, num_pkgs ) ? ;
566+ annotate_required_rust_version ( ws, resolve , & mut changes ) ;
566567
568+ status_locking ( ws, num_pkgs) ?;
567569 for change in changes. values ( ) {
568570 if change. is_member . unwrap_or ( false ) {
569571 continue ;
@@ -586,7 +588,7 @@ fn print_lockfile_sync(
586588 } ;
587589
588590 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 ) ;
590592 let latest = report_latest ( & possibilities, package_id) ;
591593 let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
592594
@@ -610,15 +612,16 @@ fn print_lockfile_updates(
610612 precise : bool ,
611613 registry : & mut PackageRegistry < ' _ > ,
612614) -> CargoResult < ( ) > {
613- let changes = PackageChange :: diff ( ws, previous_resolve, resolve) ;
615+ let mut changes = PackageChange :: diff ( ws, previous_resolve, resolve) ;
614616 let num_pkgs: usize = changes
615617 . values ( )
616618 . filter ( |change| change. kind . is_new ( ) )
617619 . count ( ) ;
620+ annotate_required_rust_version ( ws, resolve, & mut changes) ;
621+
618622 if !precise {
619623 status_locking ( ws, num_pkgs) ?;
620624 }
621-
622625 let mut unchanged_behind = 0 ;
623626 for change in changes. values ( ) {
624627 let possibilities = if let Some ( query) = change. alternatives_query ( ) {
@@ -639,7 +642,7 @@ fn print_lockfile_updates(
639642 | PackageChangeKind :: Upgraded
640643 | PackageChangeKind :: Downgraded => {
641644 let package_id = change. package_id ;
642- let required_rust_version = report_required_rust_version ( ws , resolve, package_id ) ;
645+ let required_rust_version = report_required_rust_version ( resolve, change ) ;
643646 let latest = report_latest ( & possibilities, package_id) ;
644647 let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
645648
@@ -658,7 +661,7 @@ fn print_lockfile_updates(
658661 }
659662 PackageChangeKind :: Unchanged => {
660663 let package_id = change. package_id ;
661- let required_rust_version = report_required_rust_version ( ws , resolve, package_id ) ;
664+ let required_rust_version = report_required_rust_version ( resolve, change ) ;
662665 let latest = report_latest ( & possibilities, package_id) ;
663666 let note = required_rust_version. as_deref ( ) . or ( latest. as_deref ( ) ) ;
664667
@@ -734,18 +737,14 @@ fn required_rust_version(ws: &Workspace<'_>) -> Option<PartialVersion> {
734737 }
735738}
736739
737- fn report_required_rust_version (
738- ws : & Workspace < ' _ > ,
739- resolve : & Resolve ,
740- package : PackageId ,
741- ) -> Option < String > {
742- 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 ( ) {
743742 return None ;
744743 }
745- let summary = resolve. summary ( package ) ;
744+ let summary = resolve. summary ( change . package_id ) ;
746745 let package_rust_version = summary. rust_version ( ) ?;
747- let workspace_rust_version = required_rust_version ( ws ) ?;
748- 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 ) {
749748 return None ;
750749 }
751750
@@ -804,6 +803,7 @@ struct PackageChange {
804803 previous_id : Option < PackageId > ,
805804 kind : PackageChangeKind ,
806805 is_member : Option < bool > ,
806+ required_rust_version : Option < PartialVersion > ,
807807}
808808
809809impl PackageChange {
@@ -847,6 +847,7 @@ impl PackageChange {
847847 previous_id : Some ( previous_id) ,
848848 kind,
849849 is_member,
850+ required_rust_version : None ,
850851 } ;
851852 changes. insert ( change. package_id , change) ;
852853 } else {
@@ -858,6 +859,7 @@ impl PackageChange {
858859 previous_id : None ,
859860 kind,
860861 is_member,
862+ required_rust_version : None ,
861863 } ;
862864 changes. insert ( change. package_id , change) ;
863865 }
@@ -869,6 +871,7 @@ impl PackageChange {
869871 previous_id : None ,
870872 kind,
871873 is_member,
874+ required_rust_version : None ,
872875 } ;
873876 changes. insert ( change. package_id , change) ;
874877 }
@@ -881,6 +884,7 @@ impl PackageChange {
881884 previous_id : None ,
882885 kind,
883886 is_member,
887+ required_rust_version : None ,
884888 } ;
885889 changes. insert ( change. package_id , change) ;
886890 }
@@ -1076,3 +1080,46 @@ impl PackageDiff {
10761080 }
10771081 }
10781082}
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