@@ -523,9 +523,8 @@ fn print_lockfile_generation(
523523 vec ! [ ]
524524 } ;
525525
526- let package_id = change. package_id ;
527526 let required_rust_version = report_required_rust_version ( resolve, change) ;
528- let latest = report_latest ( & possibilities, package_id ) ;
527+ let latest = report_latest ( & possibilities, change ) ;
529528 let note = required_rust_version. or ( latest) ;
530529
531530 if let Some ( note) = note {
@@ -587,9 +586,8 @@ fn print_lockfile_sync(
587586 vec ! [ ]
588587 } ;
589588
590- let package_id = change. package_id ;
591589 let required_rust_version = report_required_rust_version ( resolve, change) ;
592- let latest = report_latest ( & possibilities, package_id ) ;
590+ let latest = report_latest ( & possibilities, change ) ;
593591 let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
594592
595593 ws. gctx ( ) . shell ( ) . status_with_color (
@@ -641,9 +639,8 @@ fn print_lockfile_updates(
641639 PackageChangeKind :: Added
642640 | PackageChangeKind :: Upgraded
643641 | PackageChangeKind :: Downgraded => {
644- let package_id = change. package_id ;
645642 let required_rust_version = report_required_rust_version ( resolve, change) ;
646- let latest = report_latest ( & possibilities, package_id ) ;
643+ let latest = report_latest ( & possibilities, change ) ;
647644 let note = required_rust_version. or ( latest) . unwrap_or_default ( ) ;
648645
649646 ws. gctx ( ) . shell ( ) . status_with_color (
@@ -660,9 +657,8 @@ fn print_lockfile_updates(
660657 ) ?;
661658 }
662659 PackageChangeKind :: Unchanged => {
663- let package_id = change. package_id ;
664660 let required_rust_version = report_required_rust_version ( resolve, change) ;
665- let latest = report_latest ( & possibilities, package_id ) ;
661+ let latest = report_latest ( & possibilities, change ) ;
666662 let note = required_rust_version. as_deref ( ) . or ( latest. as_deref ( ) ) ;
667663
668664 if let Some ( note) = note {
@@ -754,23 +750,42 @@ fn report_required_rust_version(resolve: &Resolve, change: &PackageChange) -> Op
754750 ) )
755751}
756752
757- fn report_latest ( possibilities : & [ IndexSummary ] , package : PackageId ) -> Option < String > {
758- if !package. source_id ( ) . is_registry ( ) {
753+ fn report_latest ( possibilities : & [ IndexSummary ] , change : & PackageChange ) -> Option < String > {
754+ let package_id = change. package_id ;
755+ if !package_id. source_id ( ) . is_registry ( ) {
759756 return None ;
760757 }
761758
762- possibilities
759+ let version_req = package_id. version ( ) . to_caret_req ( ) ;
760+ if let Some ( version) = possibilities
763761 . iter ( )
764762 . map ( |s| s. as_summary ( ) )
765- . filter ( |s| is_latest ( s. version ( ) , package . version ( ) ) )
763+ . filter ( |s| package_id . version ( ) != s. version ( ) && version_req . matches ( s . version ( ) ) )
766764 . map ( |s| s. version ( ) . clone ( ) )
767765 . max ( )
768- . map ( format_latest)
769- }
766+ {
767+ let warn = style:: WARN ;
768+ let report = format ! ( " {warn}(latest compatible: v{version}){warn:#}" ) ;
769+ return Some ( report) ;
770+ }
771+
772+ if let Some ( version) = possibilities
773+ . iter ( )
774+ . map ( |s| s. as_summary ( ) )
775+ . filter ( |s| is_latest ( s. version ( ) , package_id. version ( ) ) )
776+ . map ( |s| s. version ( ) . clone ( ) )
777+ . max ( )
778+ {
779+ let warn = if change. is_transitive . unwrap_or ( true ) {
780+ Default :: default ( )
781+ } else {
782+ style:: WARN
783+ } ;
784+ let report = format ! ( " {warn}(latest: v{version}){warn:#}" ) ;
785+ return Some ( report) ;
786+ }
770787
771- fn format_latest ( version : semver:: Version ) -> String {
772- let warn = style:: WARN ;
773- format ! ( " {warn}(latest: v{version}){warn:#}" )
788+ None
774789}
775790
776791fn is_latest ( candidate : & semver:: Version , current : & semver:: Version ) -> bool {
@@ -803,13 +818,14 @@ struct PackageChange {
803818 previous_id : Option < PackageId > ,
804819 kind : PackageChangeKind ,
805820 is_member : Option < bool > ,
821+ is_transitive : Option < bool > ,
806822 required_rust_version : Option < PartialVersion > ,
807823}
808824
809825impl PackageChange {
810826 pub fn new ( ws : & Workspace < ' _ > , resolve : & Resolve ) -> IndexMap < PackageId , Self > {
811827 let diff = PackageDiff :: new ( resolve) ;
812- Self :: with_diff ( diff, ws)
828+ Self :: with_diff ( diff, ws, resolve )
813829 }
814830
815831 pub fn diff (
@@ -818,12 +834,13 @@ impl PackageChange {
818834 resolve : & Resolve ,
819835 ) -> IndexMap < PackageId , Self > {
820836 let diff = PackageDiff :: diff ( previous_resolve, resolve) ;
821- Self :: with_diff ( diff, ws)
837+ Self :: with_diff ( diff, ws, resolve )
822838 }
823839
824840 fn with_diff (
825841 diff : impl Iterator < Item = PackageDiff > ,
826842 ws : & Workspace < ' _ > ,
843+ resolve : & Resolve ,
827844 ) -> IndexMap < PackageId , Self > {
828845 let member_ids: HashSet < _ > = ws. members ( ) . map ( |p| p. package_id ( ) ) . collect ( ) ;
829846
@@ -842,35 +859,41 @@ impl PackageChange {
842859 PackageChangeKind :: Upgraded
843860 } ;
844861 let is_member = Some ( member_ids. contains ( & package_id) ) ;
862+ let is_transitive = Some ( true ) ;
845863 let change = Self {
846864 package_id,
847865 previous_id : Some ( previous_id) ,
848866 kind,
849867 is_member,
868+ is_transitive,
850869 required_rust_version : None ,
851870 } ;
852871 changes. insert ( change. package_id , change) ;
853872 } else {
854873 for package_id in diff. removed {
855874 let kind = PackageChangeKind :: Removed ;
856875 let is_member = None ;
876+ let is_transitive = None ;
857877 let change = Self {
858878 package_id,
859879 previous_id : None ,
860880 kind,
861881 is_member,
882+ is_transitive,
862883 required_rust_version : None ,
863884 } ;
864885 changes. insert ( change. package_id , change) ;
865886 }
866887 for package_id in diff. added {
867888 let kind = PackageChangeKind :: Added ;
868889 let is_member = Some ( member_ids. contains ( & package_id) ) ;
890+ let is_transitive = Some ( true ) ;
869891 let change = Self {
870892 package_id,
871893 previous_id : None ,
872894 kind,
873895 is_member,
896+ is_transitive,
874897 required_rust_version : None ,
875898 } ;
876899 changes. insert ( change. package_id , change) ;
@@ -879,17 +902,32 @@ impl PackageChange {
879902 for package_id in diff. unchanged {
880903 let kind = PackageChangeKind :: Unchanged ;
881904 let is_member = Some ( member_ids. contains ( & package_id) ) ;
905+ let is_transitive = Some ( true ) ;
882906 let change = Self {
883907 package_id,
884908 previous_id : None ,
885909 kind,
886910 is_member,
911+ is_transitive,
887912 required_rust_version : None ,
888913 } ;
889914 changes. insert ( change. package_id , change) ;
890915 }
891916 }
892917
918+ for member_id in & member_ids {
919+ let Some ( change) = changes. get_mut ( member_id) else {
920+ continue ;
921+ } ;
922+ change. is_transitive = Some ( false ) ;
923+ for ( direct_dep_id, _) in resolve. deps ( * member_id) {
924+ let Some ( change) = changes. get_mut ( & direct_dep_id) else {
925+ continue ;
926+ } ;
927+ change. is_transitive = Some ( false ) ;
928+ }
929+ }
930+
893931 changes
894932 }
895933
0 commit comments