Partial comparators and their fully specified forms are not interchangeable with prerelease
- Dominant language
- Rust
- Stars
- 669
- Forks
- 144
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
The `Op` [docs](https://docs.rs/semver/latest/semver/enum.Op.html) describe several partial comparators as being equivalent to fully specified forms, for example:
- `>I.J` → `>=I.(J+1).0`
- `1.0.0-alpha, <1.0.0").unwrap();
let partial_minor = VersionReq::parse(">1.0.0-alpha, <1.0").unwrap();
let partial_major = VersionReq::parse(">1.0.0-alpha, <1").unwrap();
assert!(fully_specified.matches(&v));
assert!(!partial_minor.matches(&v));
assert!(!partial_major.matches(&v));
}
```
Another example showing the same shape with `>`:
```rust
use semver::{Version, VersionReq};
#[test]
fn greater_partial_and_fully_specified_forms_can_diverge() {
let v = Version::parse("1.3.0-alpha").unwrap();
let partial = VersionReq::parse(">1.2, >=1.3.0-alpha").unwrap();
let expanded = VersionReq::parse(">=1.3.0, >=1.3.0-alpha").unwrap();
assert!(partial.matches(&v));
assert!(!expanded.matches(&v));
}
```
## Expected behavior
One of the following should be true, and the docs should make it explicit:
1. The documented forms are intended as **true semantic substitutions** in `VersionReq::matches`.
In that case, replacing a partial comparator with the documented fully specified form should not change the result.
2. The current matcher behavior is intentional.
In that case, the docs should not describe these forms as unconditional equivalents, or they should add a clear caveat that the equivalence does not necessarily preserve behavior in prerelease-bearing multi-comparator requirements.
## Actual behavior
Replacing a partial comparator with the docs' fully specified form can change the result of `VersionReq::matches` when another comparator in the same requirement makes the prerelease admissible.
So while the current behavior may be intentional, the docs' current "equivalent to" wording is not substitution-safe at the public API level.
## Impacts
The implementation does **NOT** have any correctness bug, because the current behavior is intentionally covered by tests. The actionable item is really to just tighten the doc: the docs currently read like a promise of unconditional substitution, but that promise does not hold for prerelease-bearing multi-comparator requirements.
## Related context
PR #321 appears to discuss the same family of prerelease corner cases. This issue is narrower: it is about the current `Op` documentation overpromising equivalence for the existing `VersionReq::matches` API.
## Suggested fix
The smallest fix seems to be documentation:
- weaken or clarify the `Op` docs' "equivalent to" wording for partial comparators; or
- add an explicit note that these equivalences are **not** unconditional substitutions once prerelease matching across multiple comparators is involved; and
- include at least one concrete example such as:
- `>1.0.0-alpha, <1.0.0` matches `1.0.0-beta`
- `>1.0.0-alpha, <1.0` does not
If the documentation is intended to be a strong semantic guarantee, then behavior/tests would need to change instead, but that seems more likely to be a breaking change on obscure inputs.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the Op documentation linked in the issue and the public VersionReq::matches behavior; use the two reproduction examples to understand where partial and fully specified comparators diverge. Update the documentation to clarify or qualify the equivalence claim, including a prerelease example, and verify that the documented wording matches the existing behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100