Summary

This RFC proposes a policy around the crates under the rust-lang github organization that are not part of the Rust distribution (compiler or standard library). At a high level, it proposes that these crates be:

  • Governed similarly to the standard library;
  • Maintained at a similar level to the standard library, including platform support;
  • Carefully curated for quality.

Motivation

There are three main motivations behind this RFC.

Keeping std small. There is a widespread desire to keep the standard library reasonably small, and for good reason: the stability promises made in std are tied to the versioning of Rust itself, as are updates to it, meaning that the standard library has much less flexibility than other crates enjoy. While we do plan to continue to grow std, and there are legitimate reasons for APIs to live there, we still plan to take a minimalistic approach. See this discussion for more details.

The desire to keep std small is in tension with the desire to provide high-quality libraries that belong to the whole Rust community and cover a wider range of functionality. The poster child here is the regex crate, which provides vital functionality but is not part of the standard library or basic Rust distribution – and which is, in principle, under the control of the whole Rust community.

This RFC resolves the tension between a “batteries included” Rust and a small std by treating rust-lang crates as, in some sense, “the rest of the standard library”. While this doesn’t solve the entire problem of curating the library ecosystem, it offers a big step for some of the most significant/core functionality we want to commit to.

Staging std. For cases where we do want to grow the standard library, we of course want to heavily vet APIs before their stabilization. Historically we’ve done so by landing the APIs directly in std, but marked unstable, relegating their use to nightly Rust. But in many cases, new std APIs can just as well begin their life as external crates, usable on stable Rust, and ultimately stabilized wholesale. The recent std::net RFC is a good example of this phenomenon.

The main challenge to making this kind of “std staging” work is getting sufficient visibility, central management, and community buy-in for the library prior to stabilization. When there is widespread desire to extend std in a certain way, this RFC proposes that the extension can start its life as an external rust-lang crate (ideally usable by stable Rust). It also proposes an eventual migration path into std.

Cleanup. During the stabilization of std, a fair amount of functionality was moved out into external crates hosted under the rust-lang github organization. The quality and future prospects of these crates varies widely, and we would like to begin to organize and clean them up.

Detailed design

The lifecycle of a rust-lang crate

First, two additional github organizations are proposed:

  • rust-lang-nursery
  • rust-lang-deprecated

New cratess start their life in a 0.X series that lives in the rust-lang-nursery. Crates in this state do not represent a major commitment from the Rust maintainers; rather, they signal a trial period. A crate enters the nursery when (1) there is already a working body of code and (2) the library subteam approves a petition for inclusion. The petition is informal (not an RFC), and can take the form of a discuss post laying out the motivation and perhaps some high-level design principles, and linking to the working code.

If the library team accepts a crate into the nursery, they are indicating an interest in ultimately advertising the crate as “a core part of Rust”, and in maintaining the crate permanently. During the 0.X series in the nursery, the original crate author maintains control of the crate, approving PRs and so on, but the library subteam and broader community is expected to participate. As we’ll see below, nursery crates will be advertised (though not in the same way as full rust-lang crates), increasing the chances that the crate is scrutinized before being promoted to the next stage.

Eventually, a nursery crate will either fail (and move to rust-lang-deprecated) or reach a point where a 1.0 release would be appropriate. The failure case will be determined by means of an RFC.

If, on the other hand, a library reaches the 1.0 point, it is ready to be promoted into rust-lang proper. To do so, an RFC must be written outlining the motivation for the crate, the reasons that community ownership are important, and delving into the API design and its rationale design. These RFCs are intended to follow similar lines to the pre-1.0 stabilization RFCs for the standard library (such as collections or Duration) – which have been very successful in improving API design prior to stabilization. Once a “1.0 RFC” is approved by the libs team, the crate moves into the rust-lang organization, and is henceforth governed by the whole Rust community. That means in particular that significant changes (certainly those that would require a major version bump, but other substantial PRs as well) are reviewed by the library subteam and may require an RFC. On the other hand, the community has broadly agreed to maintain the library in perpetuity (unless it is later deprecated). And again, as we’ll see below, the promoted crate is very visibly advertised as part of the “core Rust” package.

Promotion to 1.0 requires first-class support on all first-tier platforms, except for platform-specific libraries.

Crates in rust-lang may issue new major versions, just like any other crates, though such changes should go through the RFC process. While the library subteam is responsible for major decisions about the library after 1.0, its original author(s) will of course wield a great deal of influence, and their objections will be given due weight in the consensus process.

Relation to std

In many cases, the above description of the crate lifecycle is complete. But some rust-lang crates are destined for std. Usually this will be clear up front.

When a std-destined crate has reached sufficient maturity, the libs subteam can call a “final comment period” for moving it into std proper. Assuming there are no blocking objections, the code is moved into std, and the original repo is left intact, with the following changes:

  • a minor version bump,
  • conditionally replacing all definitions with pub use from std (which will require the ability to cfg switch on feature/API availability – a highly-desired feature on its own).

By re-routing the library to std when available we provide seamless compatibility between users of the library externally and in std. In particular, traits and types defined in the crate are compatible across either way of importing them.

Deprecation

At some point a library may become stale – either because it failed to make it out of the nursery, or else because it was supplanted by a superior library. Nursery and rust-lang crates can be deprecated only through an RFC. This is expected to be a rare occurrence.

Deprecated crates move to rust-lang-deprecated and are subsequently minimally maintained. Alternatively, if someone volunteers to maintain the crate, ownership can be transferred externally.

Advertising

Part of the reason for having rust-lang crates is to have a clear, short list of libraries that are broadly useful, vetted and maintained. But where should this list appear?

This RFC doesn’t specify the complete details, but proposes a basic direction:

  • The crates in rust-lang should appear in the sidebar in the core rustdocs distributed with Rust, along side the standard library. (For nightly releases, we should include the nursery crates as well.)

  • The crates should also be published on crates.io, and should somehow be badged. But the design of a badging/curation system for crates.io is out of scope for this RFC.

Plan for existing crates

There are already a number of non-std crates in rust-lang. Below, we give the full list along with recommended actions:

Transfer ownership

Please volunteer if you’re interested in taking one of these on!

  • rlibc
  • semver
  • threadpool

Move to rust-lang-nursery

  • bitflags
  • getopts
  • glob
  • libc
  • log
  • rand (note, @huonw has a major revamp in the works)
  • regex
  • rustc-serialize (but will likely be replaced by serde or other approach eventually)
  • tempdir (destined for std after reworking)
  • uuid

Move to rust-lang-deprecated

  • fourcc: highly niche
  • hexfloat: niche
  • num: this is essentially a dumping ground from 1.0 stabilization; needs a complete re-think.
  • term: API needs total overhaul
  • time: needs total overhaul destined for std
  • url: replaced by https://github.com/servo/rust-url

Drawbacks

The drawbacks of this RFC are largely social:

  • Emphasizing rust-lang crates may alienate some in the Rust community, since it means that certain libraries obtain a special “blessing”. This is mitigated by the fact that these libraries also become owned by the community at large.

  • On the other hand, requiring that ownership/governance be transferred to the library subteam may be a disincentive for library authors, since they lose unilateral control of their libraries. But this is an inherent aspect of the policy design, and the vastly increased visibility of libraries is likely a strong enough incentive to overcome this downside.

Alternatives

The main alternative would be to not maintain other crates under the rust-lang umbrella, and to offer some other means of curation (the latter of which is needed in any case).

That would be a missed opportunity, however; Rust’s governance and maintenance model has been very successful so far, and given our minimalistic plans for the standard library, it is very appealing to have some other way to apply the full Rust community in taking care of additional crates.

Unresolved questions

Part of the maintenance standard for Rust is the CI infrastructure, including bors/homu. What level of CI should we provide for these crates, and how do we do it?