@@ -15,12 +15,16 @@ pub(crate) fn upgrade_requirement(
1515 // Empty matches everything, no-change.
1616 Ok ( None )
1717 } else {
18- let comparators: CargoResult < Vec < _ > > = raw_req
18+ let comparators: Vec < _ > = raw_req
1919 . comparators
2020 . into_iter ( )
21+ // Don't downgrade if pre-release was used, see https://github.com/rust-lang/cargo/issues/14178 and https://github.com/rust-lang/cargo/issues/13290.
22+ . filter ( |p| p. pre . is_empty ( ) || matches_greater ( p, version) )
2123 . map ( |p| set_comparator ( p, version) )
22- . collect ( ) ;
23- let comparators = comparators?;
24+ . collect :: < CargoResult < _ > > ( ) ?;
25+ if comparators. is_empty ( ) {
26+ return Ok ( None ) ;
27+ }
2428 let new_req = semver:: VersionReq { comparators } ;
2529 let mut new_req_text = new_req. to_string ( ) ;
2630 if new_req_text. starts_with ( '^' ) && !req. starts_with ( '^' ) {
@@ -74,6 +78,33 @@ fn set_comparator(
7478 }
7579}
7680
81+ // See https://github.com/dtolnay/semver/blob/69efd3cc770ead273a06ad1788477b3092996d29/src/eval.rs#L64-L88
82+ fn matches_greater ( cmp : & semver:: Comparator , ver : & semver:: Version ) -> bool {
83+ if ver. major != cmp. major {
84+ return ver. major > cmp. major ;
85+ }
86+
87+ match cmp. minor {
88+ None => return false ,
89+ Some ( minor) => {
90+ if ver. minor != minor {
91+ return ver. minor > minor;
92+ }
93+ }
94+ }
95+
96+ match cmp. patch {
97+ None => return false ,
98+ Some ( patch) => {
99+ if ver. patch != patch {
100+ return ver. patch > patch;
101+ }
102+ }
103+ }
104+
105+ ver. pre > cmp. pre
106+ }
107+
77108fn assign_partial_req (
78109 version : & semver:: Version ,
79110 mut pred : semver:: Comparator ,
@@ -219,8 +250,15 @@ mod test {
219250 }
220251
221252 #[ test]
222- fn caret_prerelease ( ) {
223- assert_req_bump ( "1.7.0" , "2.0.0-beta.21" , "1.7.0" ) ;
253+ fn greater_prerelease ( ) {
254+ assert_req_bump ( "1.7.0" , "2.0.0-beta.21" , None ) ;
255+ assert_req_bump ( "1.7.0" , "=2.0.0-beta.21" , None ) ;
256+ assert_req_bump ( "1.7.0" , "~2.0.0-beta.21" , None ) ;
257+ assert_req_bump ( "2.0.0-beta.20" , "2.0.0-beta.21" , None ) ;
258+ assert_req_bump ( "2.0.0-beta.21" , "2.0.0-beta.21" , None ) ;
259+ assert_req_bump ( "2.0.0-beta.22" , "2.0.0-beta.21" , "2.0.0-beta.22" ) ;
260+ assert_req_bump ( "2.0.0" , "2.0.0-beta.21" , "2.0.0" ) ;
261+ assert_req_bump ( "3.0.0" , "2.0.0-beta.21" , "3.0.0" ) ;
224262 }
225263 }
226264}
0 commit comments