mirror of https://github.com/rust-lang/rfcs
Compare commits
26 Commits
507a54bc35
...
3f99063bd5
Author | SHA1 | Date |
---|---|---|
Ian Jackson | 3f99063bd5 | |
Eric Huss | fab408e9bc | |
Eric Huss | 55f95129ce | |
Eric Huss | a35f92ee3e | |
Carol (Nichols || Goulding) | 9a1603ede3 | |
Eric Huss | 181851eedc | |
Eric Huss | 86b1be26c1 | |
Eric Huss | 70e6e43a01 | |
Eric Huss | f2c4c4fbd3 | |
Nell Shamrell | e72326713f | |
Nell Shamrell | 93afff847a | |
Nell Shamrell | 02f41ede7e | |
Nell Shamrell | 43a015de8f | |
Nell Shamrell | 461b3b4999 | |
Nell Shamrell | b52e0fd415 | |
Ian Jackson | 47d2024d85 | |
Ian Jackson | 739cb48dd6 | |
Ian Jackson | 3d34d50eb3 | |
Ian Jackson | e58464f4d1 | |
Ian Jackson | 689b5cbc35 | |
Ian Jackson | 8b4e2d4c64 | |
Ian Jackson | ac077b30a6 | |
Ian Jackson | 69bbee7c87 | |
Ian Jackson | f07d1aa98a | |
Ian Jackson | a51be12dfa | |
Ian Jackson | 2c4a2c9dd2 |
|
@ -0,0 +1,383 @@
|
|||
- Feature Name: separate_error_fmt
|
||||
- Start Date: 2023-07-19
|
||||
- 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
|
||||
|
||||
A new `error_fmt` method on `std::error::Error`,
|
||||
so that we can distinguish:
|
||||
|
||||
* Requests to just display an error for human consumption
|
||||
(`Display`)
|
||||
* The internal implementation of printing a particular error,
|
||||
excluding its `source`s (`error_fmt`).
|
||||
|
||||
Transitional and compatibility arrangements to make this workable.
|
||||
|
||||
# Motivation
|
||||
[motivation]:
|
||||
|
||||
Correctly printing errors in Rust
|
||||
(and defining errors that print correctly)
|
||||
is too hard.
|
||||
|
||||
We want to be able to get from where we are now
|
||||
to a situation with the following properties:
|
||||
|
||||
* Just printing an error with `eprintln!("{error}")` will reliably
|
||||
do something useful.
|
||||
* Errors can be printed in a fancy report-like style with inspection
|
||||
of source errors, if desired.
|
||||
* Messages, and parts of them, are not duplicated.
|
||||
* Implementing an error type isn't significantly harder than today.
|
||||
* Warts (induced by backward compatibility requirements) are avoided
|
||||
as much as possible.
|
||||
|
||||
# Guide-level explanation (synchronic - where we want to end up)
|
||||
[guide-level-explanation]: #guide-level-explanation
|
||||
|
||||
### Background (existing situation, will not be changed by this RFC)
|
||||
|
||||
Most errors should implement `std::error::Error`.
|
||||
|
||||
Errors can have a "source": an underlying error which caused this one.
|
||||
That underlying error can in turn have a source,
|
||||
forming a causal chain.
|
||||
|
||||
### Printing errors (new doctrine)
|
||||
|
||||
Errors can be printed in two main ways:
|
||||
Every error implements `Display`
|
||||
and provides an `error_fmt` method.
|
||||
|
||||
The `Display` implementation *does* print the source.
|
||||
and should be used whenever an error (possibly and its causes)
|
||||
needs to be printed for human consumption or logging.
|
||||
|
||||
The `error_fmt` method does *not* print the source of an error.
|
||||
It is called to print the details of *this* error.
|
||||
|
||||
Normally, an implementor of an error will
|
||||
provide an implementation of `error_fmt`.
|
||||
There are macro packages in the crate ecosystem to help with this.
|
||||
|
||||
An implementor of an error type will usually
|
||||
rely on a standard library default implementation
|
||||
of `Display`.
|
||||
|
||||
# Reference-level explanation
|
||||
[reference-level-explanation]: #reference-level-explanation
|
||||
|
||||
```rust
|
||||
pub trait Error: Debug + Display {
|
||||
/// Format *this* error (excluding its `source`, if there is one).
|
||||
///
|
||||
/// The default implementation is provided for backward compatibility
|
||||
/// only; all new implementations of `Error` should provide an
|
||||
/// implementation of `error_fmt`.
|
||||
///
|
||||
/// The default implementation uses `Self as Display`.
|
||||
fn error_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ... }
|
||||
|
||||
...
|
||||
}
|
||||
|
||||
/// Displays `E` and all its sources; output is similar to "error: source".
|
||||
///
|
||||
/// When used with `{:#}`, prints a multi-line "caused by" chain.
|
||||
///
|
||||
/// Does ad-hoc deduplication, as follows: Records the string of the
|
||||
/// each error displayed, and suppresses printing of the source if the
|
||||
/// source error text is textually contained within the previous error
|
||||
/// text.
|
||||
default impl<E> Display for E where E: Error { ... }
|
||||
```
|
||||
|
||||
If neither `error_fmt`, nor an explicit `Display` impl,
|
||||
is provided, a deny-by-default lint
|
||||
(or perhaps a compilation failure) is triggered.
|
||||
|
||||
## Technical background
|
||||
|
||||
Rust is confused about how to print errors.
|
||||
The key question is "should `Display` print the `source`"?
|
||||
There is no good answer.
|
||||
|
||||
"Yes" implies that every error is responsible for its own formatting,
|
||||
and can result in duplicated output.
|
||||
|
||||
"No" means that the `Display` implementation is a footgun:
|
||||
if you just print an error in the most obvious way,
|
||||
your program will print vacuous errors in the common case
|
||||
where libraries wrap up errors from lower libraries.
|
||||
|
||||
This question has been considered by the
|
||||
Error Handling Working Group.
|
||||
Their [recommendation](https://blog.rust-lang.org/inside-rust/2021/07/01/What-the-error-handling-project-group-is-working-towards.html#guidelines-for-implementing-displayfmt-and-errorsource)
|
||||
is that the answer should be "no".
|
||||
|
||||
This RFC proposes an alternative to that decision.
|
||||
Principally,
|
||||
because experience shows that the "vacuous error messages"
|
||||
problem can be quite pervasive and severe.
|
||||
By their nature, error paths are less well-tested,
|
||||
so it is important that the obvious way of error handling is correct
|
||||
(or that tooling will catch mistakes).
|
||||
|
||||
## Analysis
|
||||
|
||||
The problem stems from the fact that there are necessarily
|
||||
two error printing concepts:
|
||||
|
||||
1. Reporting a whole error including its sources,
|
||||
|
||||
2. Printing only *this* error
|
||||
|
||||
Here, (2) forms part of the implementation of (1).
|
||||
The operation (1) of printing a whole error chain
|
||||
can be done in terms of the `source()` method and
|
||||
(2) printing individual errors.
|
||||
|
||||
The question is:
|
||||
what should these two APIs be called
|
||||
and where should they live?
|
||||
|
||||
The EHWG recommendation answers this as:
|
||||
(1) should be provided by a separate reporting function,
|
||||
such as a (not yet existing) stdlib facility,
|
||||
or crates like `anyhow` and `eyre`.
|
||||
(2) should be provided through the `Display` impl.
|
||||
But this approach is is wrong:
|
||||
the "usual" way of printing an error should be (1),
|
||||
and that is what the `Display` impl ought to mean
|
||||
(since that is what `Display` is *for*).
|
||||
|
||||
In this RFC we answer these questions as follows:
|
||||
|
||||
1. Reporting a whole error is done by `Display`ing it,
|
||||
or by using a special library if you want more control.
|
||||
|
||||
2. The implementation API for "print just this error"
|
||||
is a new trait method `Error::error_fmt`.
|
||||
|
||||
The remainder of the RFC follows from this decision,
|
||||
and from the need to maintain backwards compatibility.
|
||||
|
||||
## Transition plan
|
||||
|
||||
1. Introduce the new `error_fmt` method
|
||||
and default `Display` impl
|
||||
(including necessary language/compiler features).
|
||||
|
||||
2. Packages whose MSRV is new enough
|
||||
implement `error_fmt` instead of `Display`.
|
||||
|
||||
3. For example, macro packages like `thiserror` release a major version:
|
||||
|
||||
1. newer MSRV
|
||||
2. implement `error_fmt` (as per 2.)
|
||||
3. fail to compile if a provided format error string
|
||||
includes the error's source.
|
||||
|
||||
4. In the 2024 edition,
|
||||
issue a warning for use of the provided `error_fmt`
|
||||
(ie, for non-implementation of `error_fmt`).
|
||||
|
||||
# Drawbacks
|
||||
[drawbacks]: #drawbacks
|
||||
|
||||
* This is reversing a recommendation by the Error Handling Working Group.
|
||||
(This recommendation is not, however, present in the stdlib documentation.)
|
||||
|
||||
* Almost every implementor of `Error` will need to change eventually.
|
||||
(But this is often done with macro packages.)
|
||||
|
||||
* The ad-hoc deduplication in the default `Display`
|
||||
impl is rather unprincipled,
|
||||
and involves rather too much boxing.
|
||||
(However, it is simple and effective.)
|
||||
|
||||
* This exposes the use of specialisation in the stdlib API.
|
||||
|
||||
* This introduces the use of `#[feature(specialization)]` to `core`
|
||||
rather than just `min_specialization`.
|
||||
Moreover, the proposed blanket impl does not compile with current Rust.
|
||||
Compiler work would be needed.
|
||||
|
||||
* Additionally, compiler work may be needed to provide the lint
|
||||
for failure to manually implement either `Display` or `error_fmt`.
|
||||
|
||||
* Codebases that wish to avoid using the default error formatting,
|
||||
and always want to use a custom reporter,
|
||||
will need to somehow find a way to lint for that.
|
||||
This is not a thing that clippy can currently do.
|
||||
|
||||
# Alternatives
|
||||
[alternatives]: #alternatives
|
||||
|
||||
## Firm up EHWG recommendation to *not* include source in `Display`
|
||||
|
||||
If that recommendation were followed by all types implementing `Error`,
|
||||
and all programs that wanted to print errors
|
||||
didn't just use `Display`,
|
||||
but some reporting facility that does print sources,
|
||||
then programs would have correct behaviour overall.
|
||||
|
||||
Achieving this, and maintaining that state, is not trivial.
|
||||
It would probably involve:
|
||||
|
||||
* A new lint when an `Error`'s `Display` is used,
|
||||
but `Error::source` isn't called "nearby".
|
||||
This new lint is necessary to catch the easy mistake
|
||||
of printing an error without its source;
|
||||
experience shows that this mistake can be ubiquitous in codebases
|
||||
that adopt the EHWG recommendation.
|
||||
|
||||
* A convenient new facility in the stdlib for printing errors.
|
||||
For example, a new provided method on `Error`
|
||||
that returns something that is `Display`
|
||||
and which prints the error and all its sources.
|
||||
|
||||
A downside of this approach is that the `Display`
|
||||
impl for every error is forever "wrong":
|
||||
normally, `Display` prints a thing in the most usual way,
|
||||
but for errors, `Display` is part of the implementation,
|
||||
and actual printing must be done with some kind of reporter.
|
||||
|
||||
## Marker trait or macro for implementing `Display`
|
||||
|
||||
Instead of `default impl Display for Error`,
|
||||
we could have a library function for use in `Display` impls,
|
||||
and a macro that implements `Display` in terms of it.
|
||||
|
||||
But macro calls have a much less obvious meaning
|
||||
to the reader of the code.
|
||||
|
||||
Alternatively, there could be a marker trait:
|
||||
|
||||
```rust
|
||||
pub trait ErrorDisplay { }
|
||||
|
||||
/// Displays `E` and all its sources; output is similar to "error: source".
|
||||
///
|
||||
/// When used with `{:#}`, prints a multi-line "caused by" chain.
|
||||
/// Does ad-hoc deduplication.
|
||||
impl<E> Display for E where E: Error + ErrorDisplay { ... }
|
||||
```
|
||||
|
||||
But the blanket
|
||||
`impl<E> Display for E where E: Error + ErrorDisplay`
|
||||
is rejected by the current compiler,
|
||||
because of a conflict with the blanket
|
||||
`Display` impls for references, `Pin` etc,
|
||||
if user crates `impl ErrorDisplay for &...`.
|
||||
This would still need to be dealt with by specialisation.
|
||||
|
||||
## Declare a difference between `{:#}` and `{}`
|
||||
|
||||
We could say that whether to include sources should depend on
|
||||
`fmt::alternate()`, which comes from the `#` in `{:#}`.
|
||||
|
||||
However:
|
||||
|
||||
* Conceptually, this is wrong.
|
||||
The two kinds of output are not different styles of display
|
||||
of the same information;
|
||||
indeed, they aren't really sensibly used by the same callers.
|
||||
Sources should *always* be included in errors shown to the user.
|
||||
When omitting them is required, it is not because they are clutter,
|
||||
but because somewhere else in the reporting machinery is printing them.
|
||||
|
||||
* Formatting without the source is needed only
|
||||
by error reporting/formatting machineries,
|
||||
of which there are going to be relatively few
|
||||
(and their authors will be error display experts).
|
||||
Conversely, most programmers must frequently write code to
|
||||
display of errors to the human user,
|
||||
and in that case the sources should be included.
|
||||
That suggests `{}` should include the source and
|
||||
`{:#}` should exclude it.
|
||||
But usually the output from `{:#}` is longer,
|
||||
whereas here it would be shorter.
|
||||
And `eyre::Report` has the opposite convention.
|
||||
|
||||
* The two kinds of display want to be implemented in different places:
|
||||
we want to provide a default implementation of
|
||||
the user-visible display including sources;
|
||||
conversely, we want errors to define the display
|
||||
of their own content.
|
||||
But `fmt::alternate()` isn't sensible to use for dispatch.
|
||||
|
||||
* `{:#}` vs `{}` has a better potential meaning for errors:
|
||||
do we display everything on a single line,
|
||||
or in multi-line "caused by" format.
|
||||
|
||||
## Replace the `Error` trait completely
|
||||
|
||||
This would be a very big job
|
||||
and probably highly disruptive.
|
||||
|
||||
It might involve inventing a new mechanism for allowing
|
||||
evolution of stdlib traits across editions,
|
||||
or something.
|
||||
|
||||
## Do nothing
|
||||
|
||||
We could let the ecosystem blunder on,
|
||||
perpetrating programs that produce
|
||||
vacuous or duplicated error messages.
|
||||
|
||||
# Prior art
|
||||
[prior-art]: #prior-art
|
||||
|
||||
The problems with the `Error` trait are specific to Rust.
|
||||
|
||||
The EHWG [recommends](https://blog.rust-lang.org/inside-rust/2021/07/01/What-the-error-handling-project-group-is-working-towards.html#guidelines-for-implementing-displayfmt-and-errorsource) not to print error sources as part of `Display`.
|
||||
|
||||
`anyhow::Error` etc. don't implement `std::error::Error`.
|
||||
They *do* implement a useful `Display`
|
||||
which includes all error sources.
|
||||
|
||||
`eyre::Report` provides a way to define the way errors are reported.
|
||||
Like `anyhow::Error`, it doesn't implement `std::error::Error`.
|
||||
`eyre::Report` includes error sources when printed with `{:#}`
|
||||
and not when printed with `{}`.
|
||||
|
||||
[`snafu::CleanedErrorText`](https://docs.rs/snafu/latest/snafu/struct.CleanedErrorText.html)
|
||||
implements textual error message deduplication
|
||||
which is similar in spirit to that proposed in this RFC.
|
||||
|
||||
[Arti](https://gitlab.torproject.org/tpo/core/arti)'s
|
||||
codebase follows the EHWG recommendation, and
|
||||
has [tools](https://docs.rs/tor-error/0.5.2/tor_error/trait.ErrorReport.html)
|
||||
for use in error display contexts (such as logging).
|
||||
|
||||
# Unresolved questions
|
||||
[unresolved-questions]: #unresolved-questions
|
||||
|
||||
* What should `error_fmt` be called.
|
||||
|
||||
* What about `no_std`?
|
||||
The proposed ad-hoc duplication can't sensibly be done without all cation.
|
||||
|
||||
* What about localisation and message translation?
|
||||
Are future efforts in that area going to render this all moot?
|
||||
|
||||
* Should there be a way for someone who has an `Error`
|
||||
to tell if `error_fmt` was defaulted to "use `Display`" ?
|
||||
Without this, we might never be able to get rid of
|
||||
the extra string formatting and allocations.
|
||||
|
||||
# Future possibilities
|
||||
[future-possibilities]: #future-possibilities
|
||||
|
||||
Hopefully this will be the last churn in this area.
|
||||
|
||||
The default error reporter with string deduplication
|
||||
could use some magic to discover whether the provided
|
||||
`error_fmt`-in-terms-of-`Display` was being used by a particular error.
|
||||
If it *isn't* it knows it won't need to deduplicate it;
|
||||
it then doesn't need to format to a string.
|
||||
So the old efficiency is regained.
|
|
@ -0,0 +1,82 @@
|
|||
- Feature Name: rust-lang_github_org_access_policy
|
||||
- Start Date: 2020-03-02
|
||||
|
||||
# Summary
|
||||
[summary]: #summary
|
||||
|
||||
This RFC proposes a policy for managing permissions to the [Rust-Lang GitHub Organization](https://www.github.com/rust-lang) and repositories within this organization.
|
||||
|
||||
This RFC was written in consultation with the Governance Working Group and the Infrastructure team. Most discussion took place on [this issue](https://github.com/rust-lang/wg-governance/issues/4) and [this pull request](https://github.com/rust-lang/wg-governance/pull/42).
|
||||
|
||||
# Motivation
|
||||
[motivation]: #motivation
|
||||
|
||||
Access control for the [Rust-Lang GitHub Organization](https://www.github.com/rust-lang) and repositories within that organization is currently managed either through the [rust-lang team database][db], or ad-hoc via the GitHub UI by the org owners. We need a policy that defines how these accesses are granted and managed. This will allow us to have greater security in permissions to our GitHub org, and provide transparency and clarity on how access is managed.
|
||||
|
||||
[db]: https://github.com/rust-lang/team/
|
||||
|
||||
# Guide-level explanation
|
||||
[guide-level-explanation]: #guide-level-explanation
|
||||
|
||||
## Rust-Lang GitHub Permissions Policy
|
||||
|
||||
This policy applies to both the [Rust-Lang GitHub Organization](https://github.com/rust-lang/) and all repositories within that organization.
|
||||
|
||||
### Rust-Lang Organization
|
||||
|
||||
Access to the Rust-Lang GitHub organization is managed with the [rust-lang team database][db]. The team database is managed by the [team-repo-admins], whose policies are specified in the [Team Maintenance] documentation.
|
||||
|
||||
Selected members of the [Infrastructure Team] can also be organization owners if their work requires it.
|
||||
|
||||
All GitHub accounts used to interact with the Rust-Lang GitHub organization (owner or non-owner) must have 2FA enabled.
|
||||
|
||||
[team-repo-admins]: https://github.com/rust-lang/team/blob/master/teams/team-repo-admins.toml
|
||||
[Team Maintenance]: https://forge.rust-lang.org/infra/team-maintenance.html
|
||||
[Infrastructure Team]: https://github.com/rust-lang/team/blob/master/teams/infra.toml
|
||||
|
||||
### Rust-Lang Repositories
|
||||
|
||||
Access to and permissions for repositories within the Rust-Lang organization must be administered through the [rust-lang team database][db]. Permissions should not be given to individuals, only to teams or groups.
|
||||
|
||||
GitHub provides several permission levels for access to a repository. Please refer to [GitHub's documentation](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization) for details on permission levels and what each level can do.
|
||||
|
||||
Repositories in the Rust-Lang organization should follow these permission guidelines:
|
||||
|
||||
* **Admin** --- No users or teams except for org owners should have this permission level.
|
||||
* **Maintain** --- Teams may have this permission level at their discretion for repositories the team is responsible for.
|
||||
Repositories using the [bors] bot may want to consider using the *write* permission level instead in order to deactivate the "Merge" button on PRs to enforce that merges go through bors.
|
||||
* **Write** --- Teams that are responsible for a repository should have at least this permission level.
|
||||
* **Triage** --- This role is available if teams want to give these permissions to other teams, such as for triage support. Unfortunately this role does not allow contributors to edit issue descriptions or titles, so its utility for that purpose is limited.
|
||||
* **Read** --- This role is unnecessary, and should not be used (it is generally only relevant to private repositories, and we do not have a use case for it).
|
||||
|
||||
Teams who are responsible for a repository may give access to other teams at their discretion.
|
||||
|
||||
Teams or groups may ask for repositories to be created to fulfill their needs by opening a PR to the [Team Repository][db]. It is up to the team-repo-admins to approve creating the repositories. Existing repositories that need to be transferred from outside the rust-lang organization should consult with the Infrastructure Team to fulfill that request.
|
||||
|
||||
By default, repositories should be public and allow read access to all. When needed, some repositories can have limited read access (i.e. repositories related to security).
|
||||
|
||||
Some teams - such as the moderation team - need broad access to public Rust-Lang repositories. The first way to manage this is through creating a GitHub team managed through the [Team Repository][db] and granting that team appropriate permissions to the appropriate repos. Another way is to create tooling that will allow a member of the moderation team to selectively and temporarily gain the access that they need when it is needed (such as deleting a comment or issue). For now, we are proceeding with managing access to repos for moderation through a GitHub team, however, should it be needed, we can develop tooling to apply more fine grained and time limited access.
|
||||
|
||||
Bot accounts controlled by the Infrastructure Team (such as the [triagebot]) can be granted any level of access required for them to work at the discretion of the Infrastructure Team.
|
||||
|
||||
[bors]: https://github.com/rust-lang/homu
|
||||
[triagebot]: https://forge.rust-lang.org/triagebot/index.html
|
||||
|
||||
## Implementation
|
||||
|
||||
It is the responsibility of the Leadership Council, the Infrastructure Team, and the team-repo-admins to finish the migration to implement this policy. New teams may need to be created, which is outside the scope of this RFC to define.
|
||||
|
||||
# Drawbacks
|
||||
[drawbacks]: #drawbacks
|
||||
|
||||
There can be exceptional cases where a team wants to give repository access to an individual to assist with their work. Requiring them to join or create a team in order to perform that work can be a significant hassle. Teams who find they need this frequently should consider creating a "contributors" subteam for that purpose, or to investigate other tooling to assist with what they need.
|
||||
|
||||
# Unresolved questions
|
||||
[unresolved-questions]: #unresolved-questions
|
||||
|
||||
- Should these rules applied to Rust-Lang affiliated repositories and organizations that are outside of the [Rust-Lang GitHub Org](https://www.github.com/rust-lang), such as [rust-embedded](https://github.com/rust-embedded)?
|
||||
|
||||
# Future possibilities
|
||||
|
||||
- [Custom GitHub Roles](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/about-custom-repository-roles) could be created for use cases where the existing roles do not suffice.
|
||||
- Extend tooling, such as [triagebot], to provide extended permissions that are not normally available (for example, it currently offers [labeling](https://forge.rust-lang.org/triagebot/labeling.html)).
|
|
@ -0,0 +1,82 @@
|
|||
- Feature Name: move-crates-io-team-under-dev-tools
|
||||
- Start Date: 2024-03-25
|
||||
- RFC PR: [rust-lang/rfcs#3595](https://github.com/rust-lang/rfcs/pull/3595)
|
||||
- Rust Issue: N/A
|
||||
|
||||
# Summary
|
||||
|
||||
This RFC proposes merging the Crates.io team into the Dev tools team as a subteam. The membership of the Crates.io and Dev tools teams proper remain the same.[^subteam]
|
||||
|
||||
[^subteam]: Note: Members of subteams are not automatically direct members of their parent team. So Crates.io members will be part of the wider Dev tools team family but *not* direct members of the team proper. In practical terms this means, among other things, that Crates.io team members would not have checkbox authority associated with direct Dev tool team membership, but Crates.io team members could serve as the Leadership Council representative for Dev tools.
|
||||
|
||||
# Motivation
|
||||
|
||||
The Crates.io team has a much smaller membership base than other teams when both top-level members and the number of subteams are taken into account. It is the only team without any subteams[^subteam-requirement].
|
||||
|
||||
As of 2024-03-19:
|
||||
|
||||
| Team | # of top-level members | # of subteams/WGs/PGs [^count] |
|
||||
|--|--|--|
|
||||
| Crates.io | 8 | 0 |
|
||||
| Compiler | 15 | 31 |
|
||||
| Dev tools | 6 | 11 |
|
||||
| Infrastructure | 6 | 4 |
|
||||
| Language | 5 | 19 |
|
||||
| Library | 6 | 7 |
|
||||
| Moderation[^mods] | 2 | 2 |
|
||||
|
||||
[^count]: As calculated by doing a search in the [Teams repo](https://github.com/rust-lang/team) for `subteam-of = "team-id"`
|
||||
[^mods]: The Moderation team is a special case where being a member demands high community trust and performing difficult work, and the work that the Moderation team does always needs a seat at the Leadership Council table, even though they are also small.
|
||||
|
||||
Additionally, out of the small number of crates.io team members, many either do not have bandwidth to serve on the Leadership Council or would have perceived conflicts of interest (namely, being employed by the Rust Foundation) that don't make them the best candidate for Leadership Council representative.
|
||||
|
||||
[^subteam-requirement]: This RFC is not proposing any sort of requirement such as "top-level teams must have subteams", necessarily (proposing such a requirement is left as an exercise for a future RFC). Pointing out the Crates.io team is the only top-level team without subteams is merely one signal that the Crates.io team isn't comparable to the other top-level teams.
|
||||
|
||||
[RFC 3392](https://github.com/rust-lang/rfcs/blob/master/text/3392-leadership-council.md#top-level-teams) outlines what typically qualifies a team as "top-level". While one could make the argument that the Crates.io team fits these points, there are arguably two aspects where it does not neatly fit:
|
||||
|
||||
* "Have a purview that not is a subset of another team's purview": this is hard to argue exactly as most teams don't have well defined purviews, but one could argue that Crates.io's purview is a subset of multiple teams' (see the "Alternatives" section for discussion on this point).
|
||||
|
||||
* "Be the ultimate decision-makers on all aspects of that purview": Many decisions involving the crates.io team are ultimately one or more of:
|
||||
* legal decisions or funding work done by the Foundation
|
||||
* hosting decisions made by Infrastructure
|
||||
* capabilities that interface with Cargo
|
||||
|
||||
While the Crates.io team is certainly involved in those decisions and in executing them, it's arguable whether the Crates.io team is the ultimate decision-maker of all aspects of running crates.io.
|
||||
|
||||
In the past, whether a team is "top-level" or not has not been of huge consequence. However, this is no longer true since [RFC 3392](https://github.com/rust-lang/rfcs/pull/3392) introduced the Leadership Council whose representation is based on top-level team status. RFC 3392 specifically called out the need for re-examination of which teams are top-level, and this proposal is the second attempt at such a re-examination, after [RFC 3533] that moved the Release team under the Infrastructure team.
|
||||
|
||||
Currently, the representation burden is not productive or fair: by virtue of the Crates.io team being small, more of the teams' collective time is being spent on being a representative of the Leadership Council. Additionally, the Crates.io Leadership Council representative is speaking for fewer people than other teams' representatives are.
|
||||
|
||||
For the purposes of actual decision making, the Crates.io subteam retains all decision-making power with regard to crates.io related issues (i.e., this proposal does not change who makes any particular decision and is purely a change in Council representation). This may change over time should the Dev tools team choose to structure itself in a different way.
|
||||
|
||||
# Practicalities
|
||||
|
||||
Once this proposal is accepted, the Crates.io team will move to be a subteam of Dev tools. The Dev tools team does not change its top-level form.
|
||||
|
||||
The Dev tools team's Council representative would continue to serve on the Council while the Crates.io representative would immediately stop counting as a representative for all purposes.[^plan]
|
||||
|
||||
[^plan]: It is currently the unofficial plan that Carol Nichols will step down in her role as the Crates.io representative, and Eric Huss would take over as the rep, but this would be made official after the merger through internal Dev tools team process.
|
||||
|
||||
# Alternatives
|
||||
|
||||
## Merge Crates.io into Infrastructure
|
||||
|
||||
Crates.io uses infrastructure such as Fastly, CloudFront, S3, Heroku, GitHub, and other services that are managed by the Infrastructure team. There's certainly an argument to be made that the Crates.io team belongs there, however, the docs.rs team is in a similar situation and they are a subteam of Dev tools.
|
||||
|
||||
## Be a subteam of both Dev tools and Infra
|
||||
|
||||
The Types team provides precedence for this; technically the Types team is a subteam of both the Compiler and Lang teams. However, the teams repo doesn't really support multiple inheritance. The Crates.io team would like to cultivate a closer relationship with the Cargo team especially, and thinks the relationship with the Infra team could be continued in the current manner.
|
||||
|
||||
## Creating a new team
|
||||
|
||||
There are aspects of the Crates.io Team's purview that are more policy decisions than they are implementation details, such as what information Crates.io should surface about each crate, how to handle different crate ownership situations, or what browsers the site should support.
|
||||
|
||||
There could be a new team dedicated to policy questions such as these and other questions that have currently come up to the Leadership Council. People who enjoy thinking about and discussing policies might enjoy being on this team and not being responsible for implementing the policies. People implementing the policies might enjoy not being responsible for creating the policies.
|
||||
|
||||
However, it isn't clear if a policy team would be feasible and desirable. If so, this division could be done as a future enhancement; this RFC does not prevent such.
|
||||
|
||||
# Prior Art
|
||||
|
||||
Many thanks to Ryan Levick's [RFC 3533], much of which was copy-pastaed into this one. ❤️
|
||||
|
||||
[RFC 3533]: https://github.com/rust-lang/rfcs/pull/3533
|
Loading…
Reference in New Issue