Skip to content
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

RFC process for formatting style and Rustfmt defaults #1607

Merged
merged 1 commit into from
Aug 15, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
323 changes: 323 additions & 0 deletions text/0000-style-rfcs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
- Feature Name: N/A
- Start Date: 2016-04-21
- RFC PR: (leave this empty)
- Rust Issue: N/A


# Summary
[summary]: #summary

This RFC proposes a process for deciding detailed guidelines for code
formatting, and default settings for Rustfmt. The outcome of the process should
be an approved formatting style defined by a style guide and enforced by
Rustfmt.

This RFC proposes creating a new repository under the [rust-lang](https://github.com/rust-lang)
organisation called fmt-rfcs. It will be operated in a similar manner to the
[RFCs repository](https://github.com/rust-lang/rfcs), but restricted to
formatting issues. A new [sub-team](https://github.com/rust-lang/rfcs/blob/master/text/1068-rust-governance.md#subteams)
will be created to deal with those RFCs. Both the team and repository are
expected to be temporary. Once the style guide is complete, the team can be
disbanded and the repository frozen.


# Motivation
[motivation]: #motivation

There is a need to decide on detailed guidelines for the format of Rust code. A
uniform, language-wide formatting style makes comprehending new code-bases
easier and forestalls bikeshedding arguments in teams of Rust users. The utility
of such guidelines has been proven by Go, amongst other languages.

The [Rustfmt](https://github.com/rust-lang-nursery/rustfmt) tool is
[reaching maturity](https://users.rust-lang.org/t/please-help-test-rustfmt/5386)
and currently enforces a somewhat arbitrary, lightly discussed style, with many
configurable options.

If Rustfmt is to become a widely accepted tool, there needs to be a process for
the Rust community to decide on the default style, and how configurable that
style should be.

These discussions should happen in the open and be highly visible. It is
important that the Rust community has significant input to the process. The RFC
repository would be an ideal place to have this discussion because it exists to
satisfy these goals, and is tried and tested. However, the discussion is likely
to be a high-bandwidth one (code style is a contentious and often subjective
topic, and syntactic RFCs tend to be the highest traffic ones). Therefore,
having the discussion on the RFCs repository could easily overwhelm it and make
it less useful for other important discussions.

There currently exists a [style guide](https://github.com/rust-lang/rust/tree/master/src/doc/style)
as part of the Rust documentation. This is far more wide-reaching than just
formatting style, but also not detailed enough to specify Rustfmt. This was
originally developed in its [own repository](https://github.com/rust-lang/rust-guidelines),
but is now part of the main Rust repository. That seems like a poor venue for
discussion of these guidelines due to visibility.


# Detailed design
[design]: #detailed-design

## Process

The process for style RFCs will mostly follow the [process for other RFCs](https://github.com/rust-lang/rfcs).
Anyone may submit an RFC. An overview of the process is:

* If there is no single, obvious style, then open a GitHub issue on the
fmt-rfcs repo for initial discussion. This initial discussion should identify
which Rustfmt options are required to enforce the guideline.
* Implement the style in rustfmt (behind an option if it is not the current
default). In exceptional circumstances (such as where the implementation would
require very deep changes to rustfmt), this step may be skipped.
* Write an RFC formalising the formatting convention and referencing the
implementation, submit as a PR to fmt-rfcs. The RFC should include the default
values for options to enforce the guideline and which non-default options
should be kept.
* The RFC PR will be triaged by the style team and either assigned to a team
member for [shepherding](https://github.com/rust-lang/rfcs#the-role-of-the-shepherd),
or closed.
* When discussion has reached a fixed point, the RFC PR will be put into a final
comment period (FCP).
* After FCP, the RFC will either be accepted and merged or closed.
* Implementation in Rustfmt can then be finished (including any changes due to
discussion of the RFC), and defaults are set.


### Scope of the process

This process is specifically limited to formatting style guidelines which can be
enforced by Rustfmt with its current architecture. Guidelines that cannot be
enforced by Rustfmt without a large amount of work are out of scope, even if
they only pertain to formatting.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? I'm okay (might want to check with other maintainers) with having clippy constrained by the style rfcs, and allowing any kind of style rfc that can be enforced by rustfmt or clippy (which together should cover most style guidelines except for those pertaining to overall design).

I do intend to write up a huge clippy rfc for deciding defaults at some point, but if this existed it might be possible in a more incremental fashion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered a broader focus for the style team - including lints and unenforceable conventions. However, after some discussion, we thought it would be better to keep the style team as focussed as possible in order to get a quick resolution and to be really clear about the scope of the process.


Note whether Rustfmt should be configurable at all, and if so how configurable
is a decision that should be dealt with using the formatting RFC process. That
will be a rather exceptional RFC.

### Size of RFCs

RFCs should be self-contained and coherent, whilst being as small as possible to
keep discussion focused. For example, an RFC on 'arithmetic and logic
expressions' is about the right size; 'expressions' would be too big, and
'addition' would be too small.


### When is a guideline ready for RFC?

The purpose of the style RFC process is to foster an open discussion about style
guidelines. Therefore, RFC PRs should be made early rather than late. It is
expected that there may be more discussion and changes to style RFCs than is
typical for Rust RFCs. However, at submission, RFC PRs should be completely
developed and explained to the level where they can be used as a specification.

A guideline should usually be implemented in Rustfmt **before** an RFC PR is
submitted. The RFC should be used to select an option to be the default
behaviour, rather than to identify a range of options. An RFC can propose a
combination of options (rather than a single one) as default behaviour. An RFC
may propose some reorganisation of options.

Usually a style should be widely used in the community before it is submitted as
an RFC. Where multiple styles are used, they should be covered as alternatives
in the RFC, rather than being submitted as multiple RFCs. In some cases, a style
may be proposed without wide use (we don't want to discourage innovation),
however, it should have been used in *some* real code, rather than just being
sketched out.


### Triage

RFC PRs are triaged by the style team. An RFC may be closed during triage (with
feedback for the author) if the style team think it is not specified in enough
detail, has too narrow or broad scope, or is not appropriate in some way (e.g.,
applies to more than just formatting). Otherwise, the PR will be assigned a
shepherd as for other RFCs.


### FCP

FCP will last for two weeks (assuming the team decide to meet every two weeks)
and will be announced in the style team sub-team report.


### Decision and post-decision process

The style team will make the ultimate decision on accepting or closing a style
RFC PR. Decisions should be by consensus. Most discussion should take place on
the PR comment thread, a decision should ideally be made when consensus is
reached on the thread. Any additional discussion amongst the style team will be
summarised on the thread.

If an RFC PR is accepted, it will be merged. An issue for implementation will be
filed in the appropriate place (usually the Rustfmt repository) referencing the
RFC. If the style guide needs to be updated, then an issue for that should be
filed on the Rust repository.

The author of an RFC is not required to implement the guideline. If you are
interested in working on the implementation for an 'active' RFC, but cannot
determine if someone else is already working on it, feel free to ask (e.g. by
leaving a comment on the associated issue).


## The fmt-rfcs repository

The form of the fmt-rfcs repository will follow the rfcs repository. Accepted
RFCs will live in a `text` directory, the `README.md` will include information
taken from this RFC, there will be an RFC template in the root of the
repository. Issues on the repository can be used for placeholders for future
RFCs and for preliminary discussion.

The RFC format will be illustrated by the RFC template. It will have the
following sections:

* summary
* details
* implementation
* rationale
* alternatives
* unresolved questions

The 'details' section should contain examples of both what should and shouldn't
be done, cover simple and complex cases, and the interaction with other style
guidelines.

The 'implementation' section should specify how options must be set to enforce
the guideline, and what further changes (including additional options) are
required. It should specify any renaming, reorganisation, or removal of options.

The 'rationale' section should motivate the choices behind the RFC. It should
reference existing code bases which use the proposed style. 'Alternatives'
should cover alternative possible guidelines, if appropriate.

Guidelines may include more than one acceptable rule, but should offer
guidance for when to use each rule (which should be formal enough to be used by
a tool).

For example: "a struct literal must be formatted either on a single line (with
spaces after the opening brace and before the closing brace, and with fields
separated by commas and spaces), or on multiple lines (with one field per line
and newlines after the opening brace and before the closing brace). The former
approach should be used for short struct literals, the latter for longer struct
literals. For tools, the first approach should be used when the width of the
fields (excluding commas and braces) is 16 characters. E.g.,

```
let x = Foo { a: 42, b: 34 };
let y = Foo {
a: 42,
b: 34,
c: 1000
};
```
"

(Note this is just an example, not a proposed guideline).

The repository in embryonic form lives at [nrc/fmt-rfcs](https://github.com/nrc/fmt-rfcs).
It illustrates what [issues](https://github.com/nrc/fmt-rfcs/issues/1) and
[PRs](https://github.com/nrc/fmt-rfcs/pull/2) might look like, as well as
including the RFC template. Note that typically there should be more discussion
on an issue before submitting an RFC PR.

The repository should be updated as this RFC develops, and moved to the rust-lang
GitHub organisation if this RFC is accepted.


## The style team

The style [sub-team](https://github.com/rust-lang/rfcs/blob/master/text/1068-rust-governance.md#subteams)
will be responsible for handling style RFCs and making decisions related to
code style and formatting.

Per the [governance RFC](https://github.com/rust-lang/rfcs/blob/master/text/1068-rust-governance.md),
the core team would pick a leader who would then pick the rest of the team. I
propose that the team should include members representative of the following
areas:

* Rustfmt,
* the language, tools, and libraries sub-teams (since each has a stake in code style),
* large Rust projects.

Because activity such as this hasn't been done before in the RUst community, it
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "RUst"

is hard to identify suitable candidates for the team ahead of time. The team
will probably start small and consist of core members of the Rust community. I
expect that once the process gets underway the team can be rapidly expanded with
community members who are active in the fmt-rfcs repository (i.e., submitting
and constructively commenting on RFCs).

There will be a dedicated irc channel for discussion on formatting issues:
`#rust-style`.


## Style guide

The [existing style guide](https://github.com/rust-lang/rust/tree/master/src/doc/style)
will be split into two guides: one dealing with API design and similar issues
which will be managed by the libs team, and one dealing with formatting issues
which will be managed by the style team. Note that the formatting part of the
guide may include guidelines which are not enforced by Rustfmt. Those are outside
the scope of the process defined in this RFC, but still belong in that part of
the style guide.

When RFCs are accepted the style guide may need to be updated. Towards the end
of the process, the style team should audit and edit the guide to ensure it is a
coherent document.


## Material goals

Hopefully, the style guideline process will have limited duration, one year
seems reasonable. After that time, style guidelines for new syntax could be
included with regular RFCs, or the fmt-rfcs repository could be maintained in a
less active fashion.

At the end of the process, the fmt-rfcs repository should be a fairly complete
guide for formatting Rust code, and useful as a specification for Rustfmt and
tools with similar goals, such as IDEs. In particular, there should be a
decision made on how configurable Rustfmt should be, and an agreed set of
default options. The formatting style guide in the Rust repository should be a
more human-friendly source of formatting guidelines, and should be in sync with
the fmt-rfcs repo.


# Drawbacks
[drawbacks]: #drawbacks

This RFC introduces more process and bureaucracy, and requires more meetings for
some core Rust contributors. Precious time and energy will need to be devoted to
discussions.


# Alternatives
[alternatives]: #alternatives

Benevolent dictator - a single person dictates style rules which will be
followed without question by the community. This seems to work for Go, I suspect
it will not work for Rust.

Parliamentary 'democracy' - the community 'elects' a style team (via the usual
RFC consensus process, rather than actual voting). The style team decides on
style issues without an open process. This would be more efficient, but doesn't
fit very well with the open ethos of the Rust community.

Use the RFCs repo, rather than a new repo. This would have the benefit that
style RFCs would get more visibility, and it is one less place to keep track of
for Rust community members. However, it risks overwhelming the RFC repo with
style debate.

Use issues on Rustfmt. I feel that the discussions would not have enough
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO a little obscurity for bikeshed-prone issues is somewhat a good thing. But I can see why we'd want to not do that.

visibility in this fashion, but perhaps that can be addressed by wide and
regular announcement.

Use a book format for the style repo, rather than a collection of RFCs. This
would make it easier to see how the 'final product' style guide would look.
However, I expect there will be many issues that are important to be aware of
while discussing an RFC, that are not important to include in a final guide.
Copy link
Contributor

@lambda lambda Jun 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer this alternative.

I think that for this process, even more so than the Rust language, compiler, or standard libraries, the style guide is the primary product here. Being able to see the actual diff of the changes in context, especially for some of the more cross-cutting issues, would be helpful when reviewing proposed changes.

While there are issues that are important while discussing an RFC, but not important to include in the final guide, those could just be discussed in the PR itself, rather than in a separate RFC document.

A hybrid approach could work as well, in which there was a single repository for the guide and the RFCs. That way, the RFC PR could include the text of the RFC, as well as the diff of the guide.

I think that either of these approaches, a book format with RFC PRs updating the book, or a hybrid repo with both individual RFCs and the final book, would help to avoid the issues that have prompted an RFC on the Rust RFC process about including doc changes in any new RFC. Right now, there are still a few too many places where the only place to get good information about a feature is by trawling through the RFC archives, and it would be nice to avoid that for style guide as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

FWIW, when I was working on the API style guide I wanted a hybrid -- RFCs for the rationale, and a book format for quick viewing (with links back to the RFC).


Have an existing team handle the process, rather than create a new style team.
Saves on a little bureaucracy. Candidate teams would be language and tools.
However, the language team has very little free bandwidth, and the tools team is
probably not broad enough to effectively handle the style decisions.


# Unresolved questions
[unresolved]: #unresolved-questions