Description
EDIT: the issue now has mentoring instructions. Note that to implement this, we'll need to add additional API to semver crate as well!
Cargo more-or-less enforces contract on crate authors that version 1.x+n.u
can always be used instead of 1.x.v
. That means that any semver requirement, except for ^x.y.z
, does not make sense. Moreover, exotic version requirements may version resolution significantly more complicated.
So we should lint against any sevmer requirement other than x
, x.y
or x.y.z
.
Specifically,
^x.y.z
is not necessary, because^
is default~
violates versioning contract. As a consequence Cargo will generally refuse to compile a project with two tilde dependencies with same major version.>
,>=
do not make sense, because major version upgrade, by contract, can break anything.=
is in the wrong place, lockfiles should be used to pin dependencies.<
,<=
again, version pining belongs to the lockfile.*
we already forbid. It actually makes sense for suerp-quick local development though!
The interesting not clear-cut use-case is version striding (compatibility with several major versions). For example, serde = ">= 2, < 4"
means that you are source-compatible with both serde 2
and serde 3
. However, looks like the proper solution here is for the upstream crate to do dtolnay's trick? That is, serde 2
should depend on serde 3
, and reexport it's APIs.
There are several design decisions on how to actually implement it:
-
We can warn on
cargo publish
enforcing this for crate.io crates, or we can warn on parsing Cargo.toml, enforcing this for anyone. -
We can add an opt-out mechanism. For example, we might make you to write a
reason
if you use non-standard requirement:foo = { version = "~9.2", reason = "this crate has weird rustc compatibility policy" }
. -
Finally, the most radical option, what if we flatly deprecate all forms of version specification, except for
x
,x.y
,x.y.z
? That way, we won't need to document and explain various forms of version requirements at all.
I personally am leaning towards the last option, because it makes the overall system radically simpler for the user, but I am curious if there are some real use-cases for exotic version requirements?