|
| 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 barrier 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. |
| 28 | +* Each level of indentation must be four spaces (that is, all indentation |
| 29 | + outside of string literals and comments must be a multiple of four). |
| 30 | +* The maximum width for a line is 100 characters. |
| 31 | +* A tool should be configurable for all three of these variables. |
| 32 | + |
| 33 | + |
| 34 | +### Blank lines |
| 35 | + |
| 36 | +Separate items and statements by either zero or one blank lines (i.e., one or |
| 37 | +two newlines). E.g, |
| 38 | + |
| 39 | +```rust |
| 40 | +fn foo() { |
| 41 | + let x = ...; |
| 42 | + |
| 43 | + let y = ...; |
| 44 | + let z = ...; |
| 45 | +} |
| 46 | + |
| 47 | +fn bar() {} |
| 48 | +fn baz() {} |
| 49 | +``` |
| 50 | + |
| 51 | +Formatting tools should make the bounds on blank lines configurable: there |
| 52 | +should be separate minimum and maximum numbers of newlines between both |
| 53 | +statements and (top-level) items (i.e., four options). As described above, the |
| 54 | +defaults for both statements and items should be minimum: 1, maximum: 2. |
| 55 | + |
| 56 | + |
| 57 | +### [Module-level items](items.md) |
| 58 | +### [Statements](statements.md) |
| 59 | +### [Expressions](expressions.md) |
| 60 | +### [Types](types.md) |
| 61 | + |
| 62 | + |
| 63 | +### Comments |
| 64 | + |
| 65 | +The following guidelines for comments are recommendations only, a mechanical |
| 66 | +formatter might skip formatting of comments. |
| 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 or at the end of any line in a |
| 80 | +multi-line comment. Examples: |
| 81 | + |
| 82 | +```rust |
| 83 | +// A comment on an item. |
| 84 | +struct Foo { ... } |
| 85 | + |
| 86 | +fn foo() {} // A comment after an item. |
| 87 | + |
| 88 | +pub fn foo(/* a comment before an argument */ x: T) {...} |
| 89 | +``` |
| 90 | + |
| 91 | +Comments should usually be complete sentences. Start with a capital letter, end |
| 92 | +with a period (`.`). An inline block comment may be treated as a note without |
| 93 | +punctuation. |
| 94 | + |
| 95 | +Source lines which are entirely a comment should be limited to 80 characters |
| 96 | +in length (including comment sigils, but excluding indentation) or the maximum |
| 97 | +width of the line (including comment sigils and indentation), whichever is |
| 98 | +smaller: |
| 99 | + |
| 100 | +```rust |
| 101 | +// This comment goes up to the ................................. 80 char margin. |
| 102 | + |
| 103 | +{ |
| 104 | + // This comment is .............................................. 80 chars wide. |
| 105 | +} |
| 106 | + |
| 107 | +{ |
| 108 | + { |
| 109 | + { |
| 110 | + { |
| 111 | + { |
| 112 | + { |
| 113 | + // This comment is limited by the ......................... 100 char margin. |
| 114 | + } |
| 115 | + } |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | +} |
| 120 | +``` |
| 121 | + |
| 122 | +#### Doc comments |
| 123 | + |
| 124 | +Prefer line comments (`///`) to block comments (`/** ... */`). |
| 125 | + |
| 126 | +Prefer outer doc comments (`///` or `/** ... */`), only use inner doc comments |
| 127 | +(`//!` and `/*! ... */`) to write module-level or crate-level documentation. |
| 128 | + |
| 129 | +Doc comments should come before attributes. |
| 130 | + |
| 131 | +### Attributes |
| 132 | + |
| 133 | +Put each attribute on its own line, indented to the level of the item. |
| 134 | +In the case of inner attributes (`#!`), indent it to the level of the inside of |
| 135 | +the item. Prefer outer attributes, where possible. |
| 136 | + |
| 137 | +For attributes with argument lists, format like functions. |
| 138 | + |
| 139 | +```rust |
| 140 | +#[repr(C)] |
| 141 | +#[foo(foo, bar)] |
| 142 | +struct CRepr { |
| 143 | + #![repr(C)] |
| 144 | + x: f32, |
| 145 | + y: f32, |
| 146 | +} |
| 147 | +``` |
| 148 | + |
| 149 | +For attributes with an equal sign, there should be a single space before and |
| 150 | +after the `=`, e.g., `#[foo = 42]`. |
| 151 | + |
| 152 | +There must only be a single `derive` attribute. Note for tool authors: if |
| 153 | +combining multiple `derive` attributes into a single attribute, the ordering of |
| 154 | +the derived names should be preserved. E.g., `#[derive(bar)] #[derive(foo)] |
| 155 | +struct Baz;` should be formatted to `#[derive(bar, foo)] struct Baz;`. |
| 156 | + |
| 157 | +### *small* items |
| 158 | + |
| 159 | +In many places in this guide we specify that a formatter may format an item |
| 160 | +differently if it is *small*, for example struct literals: |
| 161 | + |
| 162 | +```rust |
| 163 | +// Normal formatting |
| 164 | +Foo { |
| 165 | + f1: an_expression, |
| 166 | + f2: another_expression(), |
| 167 | +} |
| 168 | + |
| 169 | +// *small* formatting |
| 170 | +Foo { f1, f2 } |
| 171 | +``` |
| 172 | + |
| 173 | +We leave it to individual tools to decide on exactly what *small* means. In |
| 174 | +particular, tools are free to use different definitions in different |
| 175 | +circumstances. |
| 176 | + |
| 177 | +Some suitable heuristics are the size of the item (in characters) or the |
| 178 | +complexity of an item (for example, that all components must be simple names, |
| 179 | +not more complex sub-expressions). For more discussion on suitable heuristics, |
| 180 | +see [this issue](https://github.com/rust-lang-nursery/fmt-rfcs/issues/47). |
| 181 | + |
| 182 | +Tools should give the user an option to ignore such heuristics and always use |
| 183 | +the normal formatting. |
| 184 | + |
| 185 | + |
| 186 | +## [Non-formatting conventions](advice.md) |
| 187 | + |
| 188 | +## [Cargo.toml conventions](cargo.md) |
| 189 | + |
| 190 | +## [Principles used for deciding these guidelines](principles.md) |
0 commit comments