|
| 1 | +# Rust Style Guide |
| 2 | + |
| 3 | +## Motivation - why use a formatting tool? |
| 4 | + |
| 5 | +Formatting code is a mostly mechanical task which takes both time and mental |
| 6 | +effort. By using an automatic formatting tool, a programmer is relieved of |
| 7 | +this task and can concentrate on more important things. |
| 8 | + |
| 9 | +Furthermore, by sticking to an established style guide (such as this one), |
| 10 | +programmers don't need to formulate ad hoc style rules, nor do they need to |
| 11 | +debate with other programmers what style rules should be used, saving time, |
| 12 | +communication overhead, and mental energy. |
| 13 | + |
| 14 | +Humans comprehend information through pattern matching. By ensuring that all |
| 15 | +Rust code has similar formatting, less mental effort is required to comprehend a |
| 16 | +new project, lowering the bar to entry for new developers. |
| 17 | + |
| 18 | +Thus, there are productivity benefits to using a formatting tool (such as |
| 19 | +rustfmt), and even larger benefits by using a community-consistent formatting, |
| 20 | +typically by using a formatting tool's default settings. |
| 21 | + |
| 22 | + |
| 23 | +## Formatting conventions |
| 24 | + |
| 25 | +### Indentation and line width |
| 26 | + |
| 27 | +Use spaces, not tabs. Each level of indentation must be four spaces. The maximum |
| 28 | +width for a line is 100 characters. A tool should be configurable for all three |
| 29 | +of these variables. |
| 30 | + |
| 31 | + |
| 32 | +### Blank lines |
| 33 | + |
| 34 | +Separate items and statements by either zero or one blank lines (i.e., one or |
| 35 | +two newlines). E.g, |
| 36 | + |
| 37 | +```rust |
| 38 | +fn foo() { |
| 39 | + let x = ...; |
| 40 | + |
| 41 | + let y = ...; |
| 42 | + let z = ...; |
| 43 | +} |
| 44 | + |
| 45 | +fn bar() {} |
| 46 | +fn baz() {} |
| 47 | +``` |
| 48 | + |
| 49 | +Formatting tools should make the bounds on blank lines configurable: there |
| 50 | +should be separate minimum and maximum numbers of newlines between both |
| 51 | +statements and (top-level) items (i.e., four options). As described above, the |
| 52 | +defaults for both statements and items should be minimum: 1, maximum: 2. |
| 53 | + |
| 54 | + |
| 55 | +### [Module-level items](items.md) |
| 56 | +### [Statements](statements.md) |
| 57 | +### [Expressions](expressions.md) |
| 58 | +### [Types](types.md) |
| 59 | + |
| 60 | + |
| 61 | +### Comments |
| 62 | + |
| 63 | +The following guidelines are recommendations only, a mechanical formatter should |
| 64 | +not change comments except to move them within a file. To be clear this means |
| 65 | +changing the whitespace before a line comment or the whitespace before or after |
| 66 | +a block comment. |
| 67 | + |
| 68 | +Prefer line comments (`//`) to block comments (`/* ... */`). |
| 69 | + |
| 70 | +When using line comments there should be a single space after the opening sigil. |
| 71 | + |
| 72 | +When using single-line block comments there should be a single space after the |
| 73 | +opening sigil and before the closing sigil. Multi-line block comments should |
| 74 | +have a newline after the opening sigil and before the closing sigil. |
| 75 | + |
| 76 | +Prefer to put a comment on its own line. Where a comment follows code, there |
| 77 | +should be a single space before it. Where a block comment is inline, there |
| 78 | +should be surrounding whitespace as if it were an identifier or keyword. There |
| 79 | +should be no trailing whitespace after a comment. Examples: |
| 80 | + |
| 81 | +```rust |
| 82 | +// A comment on an item. |
| 83 | +struct Foo { ... } |
| 84 | + |
| 85 | +fn foo() {} // A comment after an item. |
| 86 | + |
| 87 | +pub fn foo(/* a comment before an argument */ x: T) {...} |
| 88 | +``` |
| 89 | + |
| 90 | +Comments should usually be complete sentences. Start with a capital letter, end |
| 91 | +with a period (`.`). An inline block comment may be treated as a note without |
| 92 | +punctuation. |
| 93 | + |
| 94 | +Source lines which are entirely a comment should be limited to 80 characters |
| 95 | +in length (including comment sigils, but excluding indentation) or the maximum |
| 96 | +width of the line (including comment sigils and indentation), whichever is |
| 97 | +smaller: |
| 98 | + |
| 99 | +```rust |
| 100 | +// This comment goes up to the ................................. 80 char margin. |
| 101 | + |
| 102 | +{ |
| 103 | + // This comment is .............................................. 80 chars wide. |
| 104 | +} |
| 105 | + |
| 106 | +{ |
| 107 | + { |
| 108 | + { |
| 109 | + { |
| 110 | + { |
| 111 | + { |
| 112 | + // This comment is limited by the ......................... 100 char margin. |
| 113 | + } |
| 114 | + } |
| 115 | + } |
| 116 | + } |
| 117 | + } |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +#### Doc comments |
| 122 | + |
| 123 | +Prefer line comments (`///`) to block comments (`//* ... */`). |
| 124 | + |
| 125 | +Prefer outer doc comments (`///` or `//*`), only use inner doc comments (`//!` |
| 126 | +and `//*!`) to write module-level or crate-level documentation. |
| 127 | + |
| 128 | +Doc comments should come before attributes. |
| 129 | + |
| 130 | +### Attributes |
| 131 | + |
| 132 | +Put each attribute on its own line, indented to the indentation of its item. |
| 133 | +In the case of inner attributes (`#!`), indent it to the inner indentation (the |
| 134 | +indentation of the item + 1). Prefer outer attributes, where possible. |
| 135 | + |
| 136 | +For attributes with argument lists, format like functions. |
| 137 | + |
| 138 | +```rust |
| 139 | +#[repr(C)] |
| 140 | +#[foo(foo, bar)] |
| 141 | +struct CRepr { |
| 142 | + #![repr(C)] |
| 143 | + x: f32, |
| 144 | + y: f32, |
| 145 | +} |
| 146 | +``` |
| 147 | + |
| 148 | +For attributes with an equal sign, there should be a single space before and |
| 149 | +after the `=`, e.g., `#[foo = 42]`. |
| 150 | + |
| 151 | +There must only be a single `derive` attribute. Note for tool authors: if |
| 152 | +combining multiple `derive` attributes into a single attribute, the ordering of |
| 153 | +the derived names should be preserved. E.g., `#[derive(bar)] #[derive(foo)] |
| 154 | +struct Baz;` should be formatted to `#[derive(bar, foo)] struct Baz;`. |
| 155 | + |
| 156 | +### *small* items |
| 157 | + |
| 158 | +In many places in this guide we specify that a formatter may format an item |
| 159 | +differently if it is *small*, for example struct literals: |
| 160 | + |
| 161 | +```rust |
| 162 | +// Normal formatting |
| 163 | +Foo { |
| 164 | + f1: an_expression, |
| 165 | + f2: another_expression(), |
| 166 | +} |
| 167 | + |
| 168 | +// *small* formatting |
| 169 | +Foo { f1, f2 } |
| 170 | +``` |
| 171 | + |
| 172 | +We leave it to individual tools to decide on exactly what *small* means. In |
| 173 | +particular, tools are free to use different definitions in different |
| 174 | +circumstances. |
| 175 | + |
| 176 | +Some suitable heuristics are the size of the item (in characters) or the |
| 177 | +complexity of an item (for example, that all components must be simple names, |
| 178 | +not more complex sub-expressions). For more discussion on suitable heuristics, |
| 179 | +see the discussion on [this issue](https://github.com/rust-lang-nursery/fmt-rfcs/issues/47). |
| 180 | + |
| 181 | +Tools should give the user an option to ignore such heuristics and always use |
| 182 | +the normal formatting. |
| 183 | + |
| 184 | + |
| 185 | +## [Non-formatting conventions](advice.md) |
| 186 | + |
| 187 | +## [Cargo.toml conventions](cargo.md) |
0 commit comments