-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Crate deletion allowances #3927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,90 @@ | ||||||
| - Feature Name: N/A | ||||||
| - Start Date: 2026-03-11 | ||||||
| - RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) | ||||||
| - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) | ||||||
|
|
||||||
| ## Summary | ||||||
| [summary]: #summary | ||||||
|
|
||||||
| This RFC proposes adding a number of "reasonable changes" to the current crates.io deletion policy that will allow the deletion of several "reasonable to delete" crates which currently do not qualify. | ||||||
|
|
||||||
| See the [guide-level explanation](#guide-level-explanation) for the full list. | ||||||
|
|
||||||
| ## Motivation | ||||||
| [motivation]: #motivation | ||||||
|
|
||||||
| [RFC 3660](https://rust-lang.github.io/rfcs/3660-crates-io-crate-deletions.html) currently details the requirements for deleting a crate which seem very reasonable: | ||||||
|
|
||||||
| * The crate has been published for less than 72 hours, | ||||||
| * or if all the following conditions are met: | ||||||
| * The crate has a single owner, | ||||||
| * The crate is not depended upon by any other crate on crates.io (i.e. it has no reverse dependencies), | ||||||
| * The crate has been downloaded less than 100 times for each month it has been published. | ||||||
|
|
||||||
| However, there are a few obvious exceptions that could be added to this, based upon the RFC author's experience with attempting to delete some very old crates that should meet these requirements. | ||||||
|
|
||||||
| Specifically, those crates are: | ||||||
|
|
||||||
| * [bow](https://crates.io/crates/bow), which has been broken due to an incompatability hazard for almost a decade | ||||||
| * [value](https://crates.io/crates/value), which has a single reverse-dependency through a yanked version that almost certainly used it due to a typo | ||||||
|
|
||||||
| The additions from this RFC are directly inspired by these two examples, although they are also designed to apply as broadly as possible. | ||||||
|
|
||||||
| ## Guide-level explanation (Proposal) | ||||||
| [guide-level-explanation]: #guide-level-explanation | ||||||
|
|
||||||
| The crate deletion criteria receives the following change, specifically regarding reverse dependencies which are considered by the deletion criteria: | ||||||
|
|
||||||
| * Yanked versions which are over a year old are not considered as valid reverse dependencies. If the depended crate passes the deletion criteria and gets deleted, these yanked versions may also get deleted. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
We should not be deleting old yanked versions of established crates; unless there's some malice involved, they should stick around for archival purposes. Also, consider that a crate might have a feature-flagged dependency using a feature that isn't intended for most people to use. I realize that "may also get deleted" is broad and subject to discretion, but I don't think we should leave that possibility open. We could, potentially, say something like "If the depended crate passes the deletion criteria and gets deleted, that would be taken into account for any subsequent evaluation of the depending crate or its yanked versions."
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The thought process here is to consider the case where only yanked versions contain the dependency: even just one non-yanked version having the dependency overrides this requirement and means that both versions remain. That said, you're right that deleting the versions is probably excessive; we already have crates that might not compile on crates.io and that's fine, so, there's no harm in keeping yanked versions up. (I will edit that probably later today.)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Have since updated the text to remove that bit.) |
||||||
| * If a version of a crate has been failing to compile on the latest stable for over 4 years (~1 edition cycle), it may be yanked without the approval of the crate author. Since these versions are necessarily at least four years old, they also satisfy the requirements for the above criteria. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As written, this criteria is much too broad. For instance, it's legitimate for a crate to only work on nightly, not on stable. It seems like this is written in order to enable the previous requirement. But we shouldn't be force-yanking a crate version. We might, potentially want to ignore it for the purposes of evaluating the deletion criteria.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea behind yanking is that ultimately, the version does not compile, and so it's definitely doing something weird and obscure that probably doesn't apply any more. Given Rust's strong stability guarantees, this usually only happens for inference changes that have known-minimal breakages (meaning this was already evaluated to be within those known, minimal breakages) or explicit soundness issues, which again, would have already been evaluated. And, we also can still keep yanked versions around, just, they've been signalled to not be recommended. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think yanking versions that are broken on the default toolchain (latest stable) goes beyond what yanking has traditionally been for. There are legitimate reasons for a crate version to have a different toolchain in mind, such as latest nightly or fixed version/nightly. Maybe it's relying on a feature that's on the path to stabilisation. This is the case with the Rust for Linux There are also crates that pin themselves to a certain version/nightly that's moved intermittently, usually because they rely on implementation details. The pinned version won't be the latest. I think this used to be (is?) the case for some crates in the formal verification ecosystem, but I don't recall the details. Force yanking old versions here might make it more difficult to verify old artifacts for projects that don't put Cargo.lock in version control.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right and I guess that we would have to pave a path specifically for allowing the current nightly if it turns out that a feature genuinely exists in the compiler for a full edition cycle, since it would still compile. I'll think a bit on how to word that. |
||||||
|
|
||||||
| The full deletion criteria becomes: | ||||||
|
|
||||||
| * The crate has been published for less than 72 hours, | ||||||
| * or if all the following conditions are met: | ||||||
| * The crate has a single owner, | ||||||
| * The crate has been downloaded less than 100 times for each month it has been published, | ||||||
| * The crate is not depended upon by any other crate on crates.io (i.e. it has no reverse dependencies), excluding yanked versions of crates that were published over a year ago | ||||||
|
clarfonthey marked this conversation as resolved.
Outdated
kennytm marked this conversation as resolved.
Outdated
|
||||||
|
|
||||||
| Similarly, a new policy is added, stating that: | ||||||
|
|
||||||
| * Any version of a crate which has been failing to compile on the latest stable version of Rust for over 4 years may be yanked without the approval of the crate author. | ||||||
|
|
||||||
| These changes effectively allow for long-broken crates and reverse dependencies due to mistakes to be still valid under the deletion criteria. | ||||||
|
|
||||||
| ## Reference-level explanation | ||||||
| [reference-level-explanation]: #reference-level-explanation | ||||||
|
|
||||||
| This section, for lack of anything better, will include extra comments on how these criteria will be implemented in practice. | ||||||
|
|
||||||
| In particular, the "not compiling on latest stable" requirement is effectively a catch-all for when a crate author is unavailable to yank a version, and would *always* be implemented as a manual override by crates.io staff. Since this kind of requirement would effectively only be used for passing the deletion criteria, it is very likely that the number of requests for this would be low; the requests will likely be even lower now that newer versions of cargo require that the crate compile before publishing, to avoid obvious mistakes. | ||||||
|
|
||||||
| The "yanked, older than a year" requirement should be easily doable with a PostgreSQL index, and since these reverse-dependents queries are run infrequently, it should be fine to implement into the existing code. | ||||||
|
|
||||||
| ## Drawbacks | ||||||
| [drawbacks]: #drawbacks | ||||||
|
|
||||||
| The largest drawback is that this complicates the deletion criteria and thus makes it more difficult to understand. | ||||||
|
|
||||||
| ## Rationale and alternatives | ||||||
| [rationale-and-alternatives]: #rationale-and-alternatives | ||||||
|
|
||||||
| The biggest motivation for this change is that it's simple and relatively uncontroversial. crates.io allows yanking but not unpublishing versions to help be a long-term archive of crate versions: if code was able to work before, it should be able to work now too, even if a version was yanked. However, the deletion criteria was developed explicitly to allow deleting "not very useful" crates, and it comes into obvious friction with yanked versions: a single accidental dependency can ruin a crate's opportunity to delete itself, and similarly, the crate versions that use these dependencies clearly did so by accident. | ||||||
|
|
||||||
| Cluttering the crates.io namespace with old, undesired crates helps nobody, and while there are obvious downsides to letting anyone delete whatever they want, hopefully, allowing a few more extra cases that preserve intent will be an overall improvement. | ||||||
|
|
||||||
| ## Prior art | ||||||
| [prior-art]: #prior-art | ||||||
|
|
||||||
| * [`incoherent_fundamental_impls` lint](https://github.com/rust-lang/rust/issues/46205), which was directly linked to `bow` crate as an incompatibility. The crate published an empty latest version to avoid having to keep it on the crater exceptions list. | ||||||
| * [crates.io issue filed for `value` crate](https://github.com/rust-lang/crates.io/issues/12881), where the RFC author learned how a single yanked version depending on your crate can stop deletion entirely. | ||||||
|
|
||||||
| ## Unresolved questions | ||||||
| [unresolved-questions]: #unresolved-questions | ||||||
|
|
||||||
| None currently. | ||||||
|
|
||||||
| ## Future possibilities | ||||||
| [future-possibilities]: #future-possibilities | ||||||
|
|
||||||
| These are definitely not the only possible exceptions to the deletion criteria, although the emphasis on yanking can allow for more deletion opportunities if a creator explicitly yanks a version of a crate to allow this. | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it problematic to delete any crate with dependent crates, regardless of its age?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you read the rest of the RFC?