diff --git a/0000-template.md b/0000-template.md deleted file mode 100644 index e863843..0000000 --- a/0000-template.md +++ /dev/null @@ -1,47 +0,0 @@ -- Start Date: (fill me in with today's date, YYYY-MM-DD) -- RFC Issue: (fill me in) -- RFC PR: (leave this empty) -- Implementation Issue: (leave this empty) - -# Summary -[summary]: #summary - -One para explanation of the guideline. - - -# Details -[details]: #details - -This should get into specifics and corner-cases, and include examples of code -which satisfies and violates the guideline, and it interacts with other -formatting guidelines. - -Guidelines may include more than one acceptable rule, but should offer guidance -for when to use each rule (guidance which should be formal enough to be used by -Rustfmt). - - -# Implementation -[implementation]: #implementation - -This should specify how Rustfmt 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. - - -# Rationale -[rationale]: #rationale - -This should motivate the choices behind the guideline. It should reference -existing code bases which use the proposed style. - -# Alternatives -[alternatives]: #alternatives - -What other designs have been considered? - - -# Unresolved questions -[unresolved]: #unresolved-questions - -What parts of the design are still TBD? diff --git a/guide/advice.md b/guide/advice.md deleted file mode 100644 index 28d0b3f..0000000 --- a/guide/advice.md +++ /dev/null @@ -1,35 +0,0 @@ -# Other style advice - -## Expressions - -Prefer to use Rust's expression oriented nature where possible; - -```rust -// use -let x = if y { 1 } else { 0 }; -// not -let x; -if y { - x = 1; -} else { - x = 0; -} -``` - -## Names - - * Types shall be `UpperCamelCase`, - * Enum variants shall be `UpperCamelCase`, - * Where acronyms are used in the above cases, only capitalize the first letter, e.g., `HttpRequest`. - * Struct fields shall be `snake_case`, - * Function and method names shall be `snake_case`, - * Local variables shall be `snake_case`, - * Macro names shall be `snake_case`, - * Constants (`const`s and immutable `static`s) shall be `SCREAMING_SNAKE_CASE`. - * When a name is forbidden because it is a reserved word (e.g., `crate`), use a - trailing underscore to make the name legal (e.g., `crate_`), or use raw - identifiers if possible. - -### Modules - -Avoid `#[path]` annotations where possible. diff --git a/guide/cargo.md b/guide/cargo.md deleted file mode 100644 index f4993ba..0000000 --- a/guide/cargo.md +++ /dev/null @@ -1,78 +0,0 @@ -# Cargo.toml conventions - -## Formatting conventions - -Use the same line width and indentation as Rust code. - -Put a blank line between the last key-value pair in a section and the header of -the next section. Do not place a blank line between section headers and the -key-value pairs in that section, or between key-value pairs in a section. - -Sort key names alphabetically within each section, with the exception of the -`[package]` section. Put the `[package]` section at the top of the file; put -the `name` and `version` keys in that order at the top of that section, -followed by the remaining keys other than `description` in alphabetical order, -followed by the `description` at the end of that section. - -Don't use quotes around any standard key names; use bare keys. Only use quoted -keys for non-standard keys whose names require them, and avoid introducing such -key names when possible. See the [TOML -specification](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md#table) -for details. - -Put a single space both before and after the `=` between a key and value. Do -not indent any key names; start all key names at the start of a line. - -Use multi-line strings (rather than newline escape sequences) for any string -values that include multiple lines, such as the crate description. - -For array values, such as a list of authors, put the entire list on the same -line as the key, if it fits. Otherwise, use block indentation: put a newline -after the opening square bracket, indent each item by one indentation level, -put a comma after each item (including the last), and put the closing square -bracket at the start of a line by itself after the last item. - -```rust -authors = [ - "A Uthor ", - "Another Author ", -] -``` - -For table values, such as a crate dependency with a path, write the entire -table using curly braces and commas on the same line as the key if it fits. If -the entire table does not fit on the same line as the key, separate it out into -a separate section with key-value pairs: - -```toml -[dependencies] -crate1 = { path = "crate1", version = "1.2.3" } - -[dependencies.extremely_long_crate_name_goes_here] -path = "extremely_long_path_name_goes_right_here" -version = "4.5.6" -``` - -## Metadata conventions - -The authors list should consist of strings that each contain an author name -followed by an email address in angle brackets: `Full Name `. -It should not contain bare email addresses, or names without email addresses. -(The authors list may also include a mailing list address without an associated -name.) - -The license field must contain a valid [SPDX -expression](https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60), -using valid [SPDX license names](https://spdx.org/licenses/). (As an exception, -by widespread convention, the license field may use `/` in place of ` OR `; for -example, `MIT/Apache-2.0`.) - -The homepage field, if present, must consist of a single URL, including the -scheme (e.g. `https://example.org/`, not just `example.org`.) - -Within the description field, wrap text at 80 columns. Don't start the -description field with the name of the crate (e.g. "cratename is a ..."); just -describe the crate itself. If providing a multi-sentence description, the first -sentence should go on a line by itself and summarize the crate, like the -subject of an email or commit message; subsequent sentences can then describe -the crate in more detail. diff --git a/guide/expressions.md b/guide/expressions.md deleted file mode 100644 index 1753b00..0000000 --- a/guide/expressions.md +++ /dev/null @@ -1,892 +0,0 @@ -## Expressions - -### Blocks - -A block expression should have a newline after the initial `{` and before the -terminal `}`. Any qualifier before the block (e.g., `unsafe`) should always be -on the same line as the opening brace, and separated with a single space. The -contents of the block should be block indented: - -```rust -fn block_as_stmt() { - a_call(); - - { - a_call_inside_a_block(); - - // a comment in a block - the_value - } -} - -fn block_as_expr() { - let foo = { - a_call_inside_a_block(); - - // a comment in a block - the_value - }; -} - -fn unsafe_block_as_stmt() { - a_call(); - - unsafe { - a_call_inside_a_block(); - - // a comment in a block - the_value - } -} -``` - -If a block has an attribute, it should be on its own line: - -```rust -fn block_as_stmt() { - #[an_attribute] - { - #![an_inner_attribute] - - // a comment in a block - the_value - } -} -``` - -Avoid writing comments on the same line as the braces. - -An empty block should be written as `{}`. - -A block may be written on a single line if: - -* it is either used in expression position (not statement position) or is an - unsafe block in statement position, -* it contains a single-line expression and no statements, and -* it contains no comments - -A single line block should have spaces after the opening brace and before the -closing brace. - -Examples: - -```rust -fn main() { - // Single line - let _ = { a_call() }; - let _ = unsafe { a_call() }; - - // Not allowed on one line - // Statement position. - { - a_call() - } - - // Contains a statement - let _ = { - a_call(); - }; - unsafe { - a_call(); - } - - // Contains a comment - let _ = { - // A comment - }; - let _ = { - // A comment - a_call() - }; - - // Multiple lines - let _ = { - a_call(); - another_call() - }; - let _ = { - a_call( - an_argument, - another_arg, - ) - }; -} -``` - - -### Closures - -Don't put any extra spaces before the first `|` (unless the closure is prefixed -by `move`); put a space between the second `|` and the expression of the -closure. Between the `|`s, you should use function definition syntax; however, -elide types where possible. - -Use closures without the enclosing `{}`, if possible. Add the `{}` when you have -a return type, when there are statements, when there are comments inside the -closure, or when the body expression is a control-flow expression that spans -multiple lines. If using braces, follow the rules above for blocks. Examples: - -```rust -|arg1, arg2| expr - -move |arg1: i32, arg2: i32| -> i32 { - expr1; - expr2 -} - -|| Foo { - field1, - field2: 0, -} - -|| { - if true { - blah - } else { - boo - } -} - -|x| unsafe { - expr -} -``` - - -### Struct literals - -If a struct literal is *small* it may be formatted on a single line. If not, -each field should be on its own block-indented line. There should be a -trailing comma in the multi-line form only. There should be a space after the -colon only. - -There should be a space before the opening brace. In the single-line form there -should be spaces after the opening brace and before the closing brace. - -```rust -Foo { field1, field2: 0 } -let f = Foo { - field1, - field2: an_expr, -}; -``` - -Functional record update syntax is treated like a field, but it must never have -a trailing comma. There should be no space after `..`. - -```rust -let f = Foo { - field1, - ..an_expr -}; -``` - - -### Tuple literals - -Use a single-line form where possible. There should not be spaces around the -parentheses. Where a single-line form is not possible, each element of the tuple -should be on its own block-indented line and there should be a trailing comma. - -```rust -(a, b, c) - -let x = ( - a_long_expr, - another_very_long_expr, -); -``` - - -### Tuple struct literals - -There should be no space between the identifier and the opening parenthesis. -Otherwise, follow the rules for tuple literals, e.g., `Foo(a, b)`. - - -### Enum literals - -Follow the formatting rules for the various struct literals. Prefer using the -name of the enum as a qualifying name, unless the enum is in the prelude. E.g., - -```rust -Foo::Bar(a, b) -Foo::Baz { - field1, - field2: 1001, -} -Ok(an_expr) -``` - - -### Array literals - -For simple array literals, avoid line breaking, no spaces around square -brackets, contents of the array should be separated by commas and spaces. If -using the repeating initialiser, there should be a space after the semicolon -only. Apply the same rules if using the `vec!` or similar macros (always use -square brackets here). Examples: - -```rust -fn main() { - [1, 2, 3]; - vec![a, b, c, d]; - let a = [42; 10]; -} -``` - -If a line must be broken, prefer breaking only after the `;`, if possible. -Otherwise, follow the rules below for function calls. In any case, the contents -of the initialiser should be block indented and there should be line breaks -after the opening bracket and before the closing bracket: - -```rust -fn main() { - [ - a_long_expression(); - 1234567890 - ] - let x = [ - an_expression, - another_expression, - a_third_expression, - ]; -} -``` - - -### Array accesses, indexing, and slicing. - -No spaces around the square brackets, avoid breaking lines if possible, never -break a line between the target expression and the opening bracket. If the -indexing expression covers multiple lines, then it should be block indented and -there should be newlines after the opening brackets and before the closing -bracket. However, this should be avoided where possible. - -Examples: - -```rust -fn main() { - foo[42]; - &foo[..10]; - bar[0..100]; - foo[4 + 5 / bar]; - a_long_target[ - a_long_indexing_expression - ]; -} -``` - -### Unary operations - -Do not include a space between a unary op and its operand (i.e., `!x`, not -`! x`). However, there must be a space after `&mut`. Avoid line-breaking -between a unary operator and its operand. - -### Binary operations - -Do include spaces around binary ops (i.e., `x + 1`, not `x+1`) (including `=` -and other assignment operators such as `+=` or `*=`). - -For comparison operators, because for `T op U`, `&T op &U` is also implemented: -if you have `t: &T`, and `u: U`, prefer `*t op u` to `t op &u`. In general, -within expressions, prefer dereferencing to taking references. - -Use parentheses liberally, do not necessarily elide them due to precedence. -Tools should not automatically insert or remove parentheses. Do not use spaces -to indicate precedence. - -If line-breaking, put the operator on a new line and block indent. Put each -sub-expression on its own line. E.g., - -```rust -foo_bar - + bar - + baz - + qux - + whatever -``` - -Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather -than at other binary operators. - -### Control flow - -Do not include extraneous parentheses for `if` and `while` expressions. - -```rust -if true { -} -``` - -is better than - -```rust -if (true) { -} -``` - -Do include extraneous parentheses if it makes an arithmetic or logic expression -easier to understand (`(x * 15) + (y * 20)` is fine) - -### Function calls - -Do not put a space between the function name, and the opening parenthesis. - -Do not put a space between an argument, and the comma which follows. - -Do put a space between an argument, and the comma which precedes it. - -Prefer not to break a line in the callee expression. - -#### Single-line calls - -Do not put a space between the function name and open paren, between the open -paren and the first argument, or between the last argument and the close paren. - -Do not put a comma after the last argument. - -```rust -foo(x, y, z) -``` - -#### Multi-line calls - -If the function call is not *small*, it would otherwise over-run the max width, -or any argument or the callee is multi-line, then the call should be formatted -across multiple lines. In this case, each argument should be on its own -block-indented line, there should be a newline after the opening parenthesis -and before the closing parenthesis, and there should be a trailing comma. E.g., - -```rust -a_function_call( - arg1, - a_nested_call(a, b), -) -``` - - -### Method calls - -Follow the function rules for calling. - -Do not put any spaces around the `.`. - -```rust -x.foo().bar().baz(x, y, z); -``` - - -### Macro uses - -Macros which can be parsed like other constructs should be formatted like those -constructs. For example, a macro use `foo!(a, b, c)` can be parsed like a -function call (ignoring the `!`), therefore it should be formatted following the -rules for function calls. - -#### Special case macros - -Macros which take a format string and where all other arguments are *small* may -be formatted with arguments before and after the format string on a single line -and the format string on its own line, rather than putting each argument on its -own line. For example, - -```rust -println!( - "Hello {} and {}", - name1, name2, -); - -assert_eq!( - x, y, - "x and y were not equal, see {}", - reason, -); -``` - - -### Casts (`as`) - -Put spaces before and after `as`: - -```rust -let cstr = "Hi\0" as *const str as *const [u8] as *const std::os::raw::c_char; -``` - - -### Chains of fields and method calls - -A chain is a sequence of field accesses and/or method calls. A chain may also -include the try operator ('?'). E.g., `a.b.c().d` or `foo?.bar().baz?`. - -Prefer formatting on one line if possible, and the chain is *small*. If -formatting on multiple lines, each field access or method call in the chain -should be on its own line with the line-break before the `.` and after any `?`. -Each line should be block-indented. E.g., - -```rust -let foo = bar - .baz? - .qux(); -``` - -If the length of the last line of the first element plus its indentation is -less than or equal to the indentation of the second line (and there is space), -then combine the first and second lines, e.g., - -```rust -x.baz? - .qux() - -let foo = x - .baz? - .qux(); - -foo( - expr1, - expr2, -).baz? - .qux(); -``` - -#### Multi-line elements - -If any element in a chain is formatted across multiple lines, then that element -and any later elements must be on their own line. Earlier elements may be kept -on a single line. E.g., - -```rust -a.b.c()?.d - .foo( - an_expr, - another_expr, - ) - .bar - .baz -``` - -Note there is block indent due to the chain and the function call in the above -example. - -Prefer formatting the whole chain in multi-line style and each element on one -line, rather than putting some elements on multiple lines and some on a single -line, e.g., - -```rust -// Better -self.pre_comment - .as_ref() - .map_or(false, |comment| comment.starts_with("//")) - -// Worse -self.pre_comment.as_ref().map_or( - false, - |comment| comment.starts_with("//"), -) -``` - -### Control flow expressions - -This section covers `if`, `if let`, `loop`, `while`, `while let`, and `for` -expressions. - -The keyword, any initial clauses, and the opening brace of the block should be -on a single line. The usual rules for [block formatting](#Blocks) should be -applied to the block. - -If there is an `else` component, then the closing brace, `else`, any following -clause, and the opening brace should all be on the same line. There should be a -single space before and after the `else` keyword. For example: - -```rust -if ... { - ... -} else { - ... -} - -if let ... { - ... -} else if ... { - ... -} else { - ... -} -``` - -If the control line needs to be broken, then prefer to break before the `=` in -`* let` expressions and before `in` in a `for` expression; the following line -should be block indented. If the control line is broken for any reason, then the -opening brace should be on its own line and not indented. Examples: - -```rust -while let Some(foo) - = a_long_expression -{ - ... -} - -for foo - in a_long_expression -{ - ... -} - -if a_long_expression - && another_long_expression - || a_third_long_expression -{ - ... -} -``` - -Where the initial clause is multi-lined and ends with one or more closing -parentheses, square brackets, or braces, and there is nothing else on that line, -and that line is not indented beyond the indent on the first line of the control -flow expression, then the opening brace of the block should be put on the same -line with a preceding space. For example: - -```rust -if !self.config.file_lines().intersects( - &self.codemap.lookup_line_range( - stmt.span, - ), -) { // Opening brace on same line as initial clause. - ... -} -``` - - -#### Single line `if else` - -Formatters may place an `if else` or `if let else` on a single line if it occurs -in expression context (i.e., is not a standalone statement), it contains a -single `else` clause, and is *small*. For example: - -```rust -let y = if x { 0 } else { 1 }; - -// Examples that must be multi-line. -let y = if something_very_long { - not_small -} else { - also_not_small -}; - -if x { - 0 -} else { - 1 -} -``` - - -### Match - -Prefer not to line-break inside the discriminant expression. There must always -be a line break after the opening brace and before the closing brace. The match -arms must be block indented once: - -```rust -match foo { - // arms -} - -let x = match foo.bar.baz() { - // arms -}; -``` - -Use a trailing comma for a match arm if and only if not using a block. - -Never start a match arm pattern with `|`, e.g., - -```rust -match foo { - // Don't do this. - | foo => bar, - // Or this. - | a_very_long_pattern - | another_pattern - | yet_another_pattern - | a_forth_pattern => { - ... - } -} -``` - -Prefer - - -```rust -match foo { - foo => bar, - a_very_long_pattern - | another_pattern - | yet_another_pattern - | a_forth_pattern => { - ... - } -} -``` - -Avoid splitting the left-hand side (before the `=>`) of a match arm where -possible. If the right-hand side of the match arm is kept on the same line, -never use a block (unless the block is empty). - -If the right-hand side consists of multiple statements or has line comments or -the start of the line cannot be fit on the same line as the left-hand side, use -a block. A block may also be used in cases where the right-hand side is a macro call expression to prevent issues with expansions containing a trailing semicolon, more details [below](#macro-call-expressions). - -The body of a block arm should be block indented once. - -Examples: - -```rust -match foo { - foo => bar, - a_very_long_patten | another_pattern if an_expression() => { - no_room_for_this_expression() - } - foo => { - // A comment. - an_expression() - } - foo => { - let a = statement(); - an_expression() - } - bar => {} - // Trailing comma on last item. - foo => bar, -} -``` - -If the body is a single expression with no line comments and not a control flow -expression, then it may be started on the same line as the left-hand side. If -not, then it must be in a block. Example, - -```rust -match foo { - // A combinable expression. - foo => a_function_call(another_call( - argument1, - argument2, - )), - // A non-combinable expression - bar => { - a_function_call( - another_call( - argument1, - argument2, - ), - another_argument, - ) - } -} -``` - -#### Line-breaking - -Where it is possible to use a block form on the right-hand side and avoid -breaking the left-hand side, do that. E.g. - -```rust - // Assuming the following line does done fit in the max width - a_very_long_pattern | another_pattern => ALongStructName { - ... - }, - // Prefer this - a_very_long_pattern | another_pattern => { - ALongStructName { - ... - } - } - // To splitting the pattern. -``` - -Never break after `=>` without using the block form of the body. - -If the left-hand side must be split and there is an `if` clause, break before -the `if` and block indent. In this case, always use a block body and start the -body on a new line: - -```rust - a_very_long_pattern | another_pattern - if expr => - { - ... - } -``` - -If required to break the pattern, put each clause of the pattern on its own -line with no additional indent, breaking before the `|`. If there is an `if` -clause, then you must use the above form: - -```rust - a_very_long_pattern - | another_pattern - | yet_another_pattern - | a_forth_pattern => { - ... - } - a_very_long_pattern - | another_pattern - | yet_another_pattern - | a_forth_pattern - if expr => - { - ... - } -``` - -If the pattern is multi-line, and the last line is less wide than the indent, do -not put the `if` clause on a newline. E.g., - -```rust - Token::Dimension { - value, - ref unit, - .. - } if num_context.is_ok(context.parsing_mode, value) => { - ... - } -``` - -If every clause in a pattern is *small*, but does not fit on one line, then the -pattern may be formatted across multiple lines with as many clauses per line as -possible. Again break before a `|`: - -```rust - foo | bar | baz - | qux => { - ... - } -``` - -We define a pattern clause to be *small* if it matches the following grammar: - -``` -[small, ntp]: - - single token - - `&[single-line, ntp]` - -[small]: - - `[small, ntp]` - - unary tuple constructor `([small, ntp])` - - `&[small]` -``` - -E.g., `&&Some(foo)` matches, `Foo(4, Bar)` does not. - -#### Macro call expressions -When the right-hand side of a match arm contains a macro call expression, it may be necessary to use a block to prevent issues in expansion. - -In some cases the right-hand side may be placed on the same line as the left-hand side. E.g., - -```rust -macro_rules! expr { - () => { - true - }; -} - -fn main() { - let _val: bool = match true { - true => expr!(), - false => false, - }; -} -``` - -However, in other cases it is necessary to use a block to prevent issues in macro expansion, such as with trailing semicolons. - -```rust -macro_rules! stmt { - () => { - true; - }; -} - -fn main() { - match true { - true => { - stmt!() - } - false => {} - } -} -``` - -Note that at the time of this writing [rustc ignores these trailing semicolons](https://github.com/rust-lang/rust/issues/33953), but this guidance is provided in case that changes. - -### Combinable expressions - -Where a function call has a single argument, and that argument is formatted -across multiple-lines, the outer call may be formatted as if it were a -single-line call. The same combining behaviour may be applied to any similar -expressions which have multi-line, block-indented lists of sub-expressions -delimited by parentheses (e.g., macros or tuple struct literals). E.g., - -```rust -foo(bar( - an_expr, - another_expr, -)) - -let x = foo(Bar { - field: whatever, -}); - -foo(|param| { - action(); - foo(param) -}) -``` - -Such behaviour should extend recursively; however, tools may choose to limit the -depth of nesting. - -Only where the multi-line sub-expression is a closure with an explicit block, -this combining behaviour may be used where there are other arguments, as long as -all the arguments and the first line of the closure fit on the first line, the -closure is the last argument, and there is only one closure argument: - -```rust -foo(first_arg, x, |param| { - action(); - foo(param) -}) -``` - - -### Ranges - -Do not put spaces in ranges, e.g., `0..10`, `x..=y`, `..x.len()`, `foo..`. - -When writing a range with both upper and lower bounds, if the line must be -broken, break before the range operator and block indent the second line: - -```rust -a_long_expression - ..another_long_expression -``` - -For the sake of indicating precedence, we recommend that if either bound is a -compound expression, then use parentheses around it, e.g., `..(x + 1)`, -`(x.f)..(x.f.len())`, or `0..(x - 10)`. - - -### Hexadecimal literals - -Hexadecimal literals may use upper- or lower-case letters, but they must not be -mixed within the same literal. Projects should use the same case for all -literals, but we do not make a recommendation for either lower- or upper-case. -Tools should have an option to convert mixed case literals to upper-case, and -may have an option to convert all literals to either lower- or upper-case. - - -## Patterns - -Patterns should be formatted like their corresponding expressions. See the -section on `match` for additional formatting for patterns in match arms. diff --git a/guide/guide.md b/guide/guide.md deleted file mode 100644 index 6693f67..0000000 --- a/guide/guide.md +++ /dev/null @@ -1,190 +0,0 @@ -# Rust Style Guide - -## Motivation - why use a formatting tool? - -Formatting code is a mostly mechanical task which takes both time and mental -effort. By using an automatic formatting tool, a programmer is relieved of -this task and can concentrate on more important things. - -Furthermore, by sticking to an established style guide (such as this one), -programmers don't need to formulate ad hoc style rules, nor do they need to -debate with other programmers what style rules should be used, saving time, -communication overhead, and mental energy. - -Humans comprehend information through pattern matching. By ensuring that all -Rust code has similar formatting, less mental effort is required to comprehend a -new project, lowering the barrier to entry for new developers. - -Thus, there are productivity benefits to using a formatting tool (such as -rustfmt), and even larger benefits by using a community-consistent formatting, -typically by using a formatting tool's default settings. - - -## Formatting conventions - -### Indentation and line width - -* Use spaces, not tabs. -* Each level of indentation must be 4 spaces (that is, all indentation - outside of string literals and comments must be a multiple of four). -* The maximum width for a line is 100 characters. -* A tool should be configurable for all three of these variables. - - -### Blank lines - -Separate items and statements by either zero or one blank lines (i.e., one or -two newlines). E.g, - -```rust -fn foo() { - let x = ...; - - let y = ...; - let z = ...; -} - -fn bar() {} -fn baz() {} -``` - -Formatting tools should make the bounds on blank lines configurable: there -should be separate minimum and maximum numbers of newlines between both -statements and (top-level) items (i.e., four options). As described above, the -defaults for both statements and items should be minimum: 1, maximum: 2. - - -### [Module-level items](items.md) -### [Statements](statements.md) -### [Expressions](expressions.md) -### [Types](types.md) - - -### Comments - -The following guidelines for comments are recommendations only, a mechanical -formatter might skip formatting of comments. - -Prefer line comments (`//`) to block comments (`/* ... */`). - -When using line comments there should be a single space after the opening sigil. - -When using single-line block comments there should be a single space after the -opening sigil and before the closing sigil. Multi-line block comments should -have a newline after the opening sigil and before the closing sigil. - -Prefer to put a comment on its own line. Where a comment follows code, there -should be a single space before it. Where a block comment is inline, there -should be surrounding whitespace as if it were an identifier or keyword. There -should be no trailing whitespace after a comment or at the end of any line in a -multi-line comment. Examples: - -```rust -// A comment on an item. -struct Foo { ... } - -fn foo() {} // A comment after an item. - -pub fn foo(/* a comment before an argument */ x: T) {...} -``` - -Comments should usually be complete sentences. Start with a capital letter, end -with a period (`.`). An inline block comment may be treated as a note without -punctuation. - -Source lines which are entirely a comment should be limited to 80 characters -in length (including comment sigils, but excluding indentation) or the maximum -width of the line (including comment sigils and indentation), whichever is -smaller: - -```rust -// This comment goes up to the ................................. 80 char margin. - -{ - // This comment is .............................................. 80 chars wide. -} - -{ - { - { - { - { - { - // This comment is limited by the ......................... 100 char margin. - } - } - } - } - } -} -``` - -#### Doc comments - -Prefer line comments (`///`) to block comments (`/** ... */`). - -Prefer outer doc comments (`///` or `/** ... */`), only use inner doc comments -(`//!` and `/*! ... */`) to write module-level or crate-level documentation. - -Doc comments should come before attributes. - -### Attributes - -Put each attribute on its own line, indented to the level of the item. -In the case of inner attributes (`#!`), indent it to the level of the inside of -the item. Prefer outer attributes, where possible. - -For attributes with argument lists, format like functions. - -```rust -#[repr(C)] -#[foo(foo, bar)] -struct CRepr { - #![repr(C)] - x: f32, - y: f32, -} -``` - -For attributes with an equal sign, there should be a single space before and -after the `=`, e.g., `#[foo = 42]`. - -There must only be a single `derive` attribute. Note for tool authors: if -combining multiple `derive` attributes into a single attribute, the ordering of -the derived names should be preserved. E.g., `#[derive(bar)] #[derive(foo)] -struct Baz;` should be formatted to `#[derive(bar, foo)] struct Baz;`. - -### *small* items - -In many places in this guide we specify that a formatter may format an item -differently if it is *small*, for example struct literals: - -```rust -// Normal formatting -Foo { - f1: an_expression, - f2: another_expression(), -} - -// *small* formatting -Foo { f1, f2 } -``` - -We leave it to individual tools to decide on exactly what *small* means. In -particular, tools are free to use different definitions in different -circumstances. - -Some suitable heuristics are the size of the item (in characters) or the -complexity of an item (for example, that all components must be simple names, -not more complex sub-expressions). For more discussion on suitable heuristics, -see [this issue](https://github.com/rust-lang-nursery/fmt-rfcs/issues/47). - -Tools should give the user an option to ignore such heuristics and always use -the normal formatting. - - -## [Non-formatting conventions](advice.md) - -## [Cargo.toml conventions](cargo.md) - -## [Principles used for deciding these guidelines](principles.md) diff --git a/guide/items.md b/guide/items.md deleted file mode 100644 index 82e4aa1..0000000 --- a/guide/items.md +++ /dev/null @@ -1,565 +0,0 @@ -## Items - -`extern crate` statements must be first in a file. They must be ordered -alphabetically. - -`use` statements, and module *declarations* (`mod foo;`, not `mod { ... }`) -must come before other items. We recommend that imports come before module -declarations; if imports and modules are separated, then they should be ordered -alphabetically. When sorting, `self` and `super` must come before any other -names. Module declarations should not be moved if they are annotated with -`#[macro_use]`, since that may be semantics changing. - -Tools should make the above ordering optional. - - -### Function definitions - -In Rust, one finds functions by searching for `fn [function-name]`; It's -important that you style your code so that it's very searchable in this way. - -The proper ordering and spacing is: - -```rust -[pub] [unsafe] [extern ["ABI"]] fn foo(arg1: i32, arg2: i32) -> i32 { - ... -} -``` - -Avoid comments within the signature itself. - -If the function signature does not fit on one line, then break after the opening -parenthesis and before the closing parenthesis and put each argument on its own -block-indented line. For example, - -```rust -fn foo( - arg1: i32, - arg2: i32, -) -> i32 { - ... -} -``` - -Note the trailing comma on the last argument. - - -### Tuples and tuple structs - -Write the type list as you would a parameter list to a function. - -Build a tuple or tuple struct as you would call a function. - -#### Single-line - -```rust -struct Bar(Type1, Type2); - -let x = Bar(11, 22); -let y = (11, 22, 33); -``` - -### Enums - -In the declaration, put each variant on its own line, block indented. - -Format each variant accordingly as either a struct, tuple struct, or identifier, -which doesn't require special formatting (but without the `struct` keyword. - -```rust -enum FooBar { - First(u32), - Second, - Error { - err: Box, - line: u32, - }, -} -``` - -If a struct variant is [*small*](#small-items), it may be formatted on -one line. In this case, do not use a trailing comma for the field list, but do -put spaces around each brace: - -```rust -enum FooBar { - Error { err: Box, line: u32 }, -} -``` - -In an enum with multiple struct variants, if any struct variant is written on -multiple lines, then the multi-line formatting should be used for all struct -variants. However, such a situation might be an indication that you should -factor out the fields of the variant into their own struct. - - -### Structs and Unions - -Struct names follow on the same line as the `struct` keyword, with the opening -brace on the same line when it fits within the right margin. All struct fields -are indented once and end with a trailing comma. The closing brace is not -indented and appears on its own line. - -```rust -struct Foo { - a: A, - b: B, -} -``` - -If and only if the type of a field does not fit within the right margin, it is -pulled down to its own line and indented again. - -```rust -struct Foo { - a: A, - long_name: - LongType, -} -``` - -Prefer using a unit struct (e.g., `struct Foo;`) to an empty struct (e.g., -`struct Foo();` or `struct Foo {}`, these only exist to simplify code -generation), but if you must use an empty struct, keep it on one line with no -space between the braces: `struct Foo;` or `struct Foo {}`. - -The same guidelines are used for untagged union declarations. - -```rust -union Foo { - a: A, - b: B, - long_name: - LongType, -} -``` - - -### Tuple structs - -Put the whole struct on one line if possible. Types in the parentheses should be -separated by a comma and space with no trailing comma. No spaces around the -parentheses or semi-colon: - -```rust -pub struct Foo(String, u8); -``` - -Prefer unit structs to empty tuple structs (these only exist to simplify code -generation), e.g., `struct Foo;` rather than `struct Foo();`. - -For more than a few fields, prefer a proper struct with named fields. Given -this, a tuple struct should always fit on one line. If it does not, block format -the fields with a field on each line and a trailing comma: - -```rust -pub struct Foo( - String, - u8, -); -``` - - -### Traits - -Trait items should be block-indented. If there are no items, the trait may be -formatted on a single line. Otherwise there should be line-breaks after the -opening brace and before the closing brace: - -```rust -trait Foo {} - -pub trait Bar { - ... -} -``` - -If the trait has bounds, there should be a space after the colon but not before -and before and after each `+`, e.g., - -```rust -trait Foo: Debug + Bar {} -``` - -Prefer not to line-break in the bounds if possible (consider using a `where` -clause). Prefer to break between bounds than to break any individual bound. If -you must break the bounds, put each bound (including the first) on its own -block-indented line, break before the `+` and put the opening brace on its own -line: - -```rust -pub trait IndexRanges: - Index, Output=Self> - + Index, Output=Self> - + Index, Output=Self> - + Index -{ - ... -} -``` - - -### Impls - -Impl items should be block indented. If there are no items, the impl may be -formatted on a single line. Otherwise there should be line-breaks after the -opening brace and before the closing brace: - -```rust -impl Foo {} - -impl Bar for Foo { - ... -} -``` - -Avoid line-breaking in the signature if possible. If a line break is required in -a non-inherent impl, break immediately before `for`, block indent the concrete type -and put the opening brace on its own line: - -```rust -impl Bar - for Foo -{ - ... -} -``` - - -### Extern crate - -`extern crate foo;` - -Use spaces around keywords, no spaces around the semi-colon. - - -### Modules - -```rust -mod foo { -} -``` - -```rust -mod foo; -``` - -Use spaces around keywords and before the opening brace, no spaces around the -semi-colon. - -### macro\_rules! - -Use `{}` for the full definition of the macro. - -```rust -macro_rules! foo { -} -``` - - -### Generics - -Prefer to put a generics clause on one line. Break other parts of an item -declaration rather than line-breaking a generics clause. If a generics clause is -large enough to require line-breaking, you should prefer to use a `where` clause -instead. - -Do not put spaces before or after `<` nor before `>`. Only put a space after `>` -if it is followed by a word or opening brace, not an opening parenthesis. There -should be a space after each comma and no trailing comma. - -```rust -fn foo(x: Vec, y: Vec) ... - -impl SomeType { ... -``` - -If the generics clause must be formatted across multiple lines, each parameter -should have its own block-indented line, there should be newlines after the -opening bracket and before the closing bracket, and there should be a trailing -comma. - -```rust -fn foo< - T: Display, - U: Debug, ->(x: Vec, y: Vec) ... -``` - -If an associated type is bound in a generic type, then there should be spaces on -either side of the `=`: - -```rust -> -``` - -Prefer to use single-letter names for generic parameters. - - -### `where` clauses - -These rules apply for `where` clauses on any item. - -A `where` clause may immediately follow a closing bracket of any kind. -Otherwise, it must start a new line, with no indent. Each component of a `where` -clause must be on its own line and be block indented. There should be a trailing -comma, unless the clause is terminated with a semicolon. If the `where` clause -is followed by a block (or assignment), the block should be started on a new -line. Examples: - -```rust -fn function(args) -where - T: Bound, - U: AnotherBound, -{ - body -} - -fn foo( - args -) -> ReturnType -where - T: Bound, -{ - body -} - -fn foo( - args, -) where - T: Bound, - U: AnotherBound, -{ - body -} - -fn foo( - args -) -> ReturnType -where - T: Bound, - U: AnotherBound; // Note, no trailing comma. - -// Note that where clauses on `type` aliases are not enforced and should not -// be used. -type Foo -where - T: Bound -= Bar; -``` - -If a `where` clause is very short, we recommend using an inline bound on the -type parameter. - - -If a component of a `where` clause is long, it may be broken before `+` and -further block indented. Each bound should go on its own line. E.g., - -```rust -impl IndexRanges for T -where - T: Index, Output = Self::Output> - + Index, Output = Self::Output> - + Index, Output = Self::Output> - + Index, Output = Self::Output> - + Index, Output = Self::Output> + Index -``` - -#### Option - `where_single_line` - -`where_single_line` is `false` by default. If `true`, then a where clause with -exactly one component may be formatted on a single line if the rest of the -item's signature is also kept on one line. In this case, there is no need for a -trailing comma and if followed by a block, no need for a newline before the -block. E.g., - -```rust -// May be single-lined. -fn foo(args) -> ReturnType -where T: Bound { - body -} - -// Must be multi-lined. -fn foo( - args -) -> ReturnType -where - T: Bound, -{ - body -} -``` - - -### Type aliases - -Type aliases should generally be kept on one line. If necessary to break the -line, do so after the `=`; the right-hand-side should be block indented: - -```rust -pub type Foo = Bar; - -// If multi-line is required -type VeryLongType = - AnEvenLongerType>; -``` - -Where possible avoid `where` clauses and keep type constraints inline. Where -that is not possible split the line before and after the `where` clause (and -split the `where` clause as normal), e.g., - -```rust -type VeryLongType -where - T: U::AnAssociatedType, - U: SomeBound, -= AnEvenLongerType>; -``` - - -### Associated types - -Associated types should follow the guidelines above for type aliases. Where an -associated type has a bound, there should be a space after the colon but not -before: - -```rust -pub type Foo: Bar; -``` - - -### extern items - -When writing extern items (such as `extern "C" fn`), always be explicit about -the ABI. For example, write `extern "C" fn foo ...`, not `extern fn foo ...`, or -`extern "C" { ... }`. - - -### Imports (`use` statements) - -If an import can be formatted on one line, do so. There should be no spaces -around braces. - -```rust -use a::b::c; -use a::b::d::*; -use a::b::{foo, bar, baz}; -``` - - -#### Large list imports - -Prefer to use multiple imports rather than a multi-line import. However, tools -should not split imports by default (they may offer this as an option). - -If an import does require multiple lines (either because a list of single names -does not fit within the max width, or because of the rules for nested imports -below), then break after the opening brace and before the closing brace, use a -trailing comma, and block indent the names. - - -```rust -// Prefer -foo::{long, list, of, imports}; -foo::{more, imports}; - -// If necessary -foo::{ - long, list, of, imports, more, - imports, // Note trailing comma -}; -``` - - -#### Ordering of imports - -A *group* of imports is a set of imports on the same or sequential lines. One or -more blank lines or other items (e.g., a function) separate groups of imports. - -Within a group of imports, imports must be sorted ascii-betically. Groups of -imports must not be merged or re-ordered. - - -E.g., input: - -```rust -use d; -use c; - -use b; -use a; -``` - -output: - -```rust -use c; -use d; - -use a; -use b; -``` - -Because of `macro_use`, attributes must also start a new group and prevent -re-ordering. - -Note that tools which only have access to syntax (such as Rustfmt) cannot tell -which imports are from an external crate or the std lib, etc. - - -#### Ordering list import - -Names in a list import must be sorted ascii-betically, but with `self` and -`super` first, and groups and glob imports last. This applies recursively. For -example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g., -`use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, b::{self, r, s}};`. - - -#### Normalisation - -Tools must make the following normalisations: - -* `use a::self;` -> `use a;` -* `use a::{};` -> (nothing) -* `use a::{b};` -> `use a::b;` - -And must apply these recursively. - -Tools must not otherwise merge or un-merge import lists or adjust glob imports -(without an explicit option). - - -#### Nested imports - -If there are any nested imports in a list import, then use the multi-line form, -even if the import fits on one line. Each nested import must be on its own line, -but non-nested imports must be grouped on as few lines as possible. - -For example, - -```rust -use a::b::{ - x, y, z, - u::{...}, - w::{...}, -}; -``` - - -#### Merging/un-merging imports - -An example: - -```rust -// Un-merged -use a::b; -use a::c::d; - -// Merged -use a::{b, c::d}; -``` - -Tools must not merge or un-merge imports by default. They may offer merging or -un-merging as an option. diff --git a/guide/principles.md b/guide/principles.md deleted file mode 100644 index b02b3c0..0000000 --- a/guide/principles.md +++ /dev/null @@ -1,51 +0,0 @@ -# Guiding principles and rationale - -When deciding on style guidelines, the style team tried to be guided by the -following principles (in rough priority order): - -* readability - - scan-ability - - avoiding misleading formatting - - accessibility - readable and editable by users using the the widest - variety of hardware, including non-visual accessibility interfaces - - readability of code when quoted in rustc error messages - -* aesthetics - - sense of 'beauty' - - consistent with other languages/tools - -* specifics - - compatibility with version control practices - preserving diffs, - merge-friendliness, etc. - - preventing right-ward drift - - minimising vertical space - -* application - - ease of manual application - - ease of implementation (in Rustfmt, and in other tools/editors/code generators) - - internal consistency - - simplicity of formatting rules - - -## Overarching guidelines - -Prefer block indent over visual indent. E.g., - -```rust -// Block indent -a_function_call( - foo, - bar, -); - -// Visual indent -a_function_call(foo, - bar); -``` - -This makes for smaller diffs (e.g., if `a_function_call` is renamed in the above -example) and less rightward drift. - -Lists should have a trailing comma when followed by a newline, see the block -indent example above. This choice makes moving code (e.g., by copy and paste) -easier and makes smaller diffs. diff --git a/guide/statements.md b/guide/statements.md deleted file mode 100644 index 9c3eba1..0000000 --- a/guide/statements.md +++ /dev/null @@ -1,150 +0,0 @@ -### Let statements - -There should be spaces after the `:` and on both sides of the `=` (if they are -present). No space before the semi-colon. - -```rust -// A comment. -let pattern: Type = expr; - -let pattern; -let pattern: Type; -let pattern = expr; -``` - -If possible the declaration should be formatted on a single line. If this is not -possible, then try splitting after the `=`, if the declaration can fit on two -lines. The expression should be block indented. - -```rust -let pattern: Type = - expr; -``` - -If the first line does not fit on a single line, then split after the colon, -using block indentation. If the type covers multiple lines, even after line- -breaking after the `:`, then the first line may be placed on the same line as -the `:`, subject to the [combining rules](https://github.com/rust-lang-nursery/fmt-rfcs/issues/61) (WIP). - - -```rust -let pattern: - Type = - expr; -``` - -e.g, - -```rust -let Foo { - f: abcd, - g: qwer, -}: Foo = - Foo { f, g }; - -let (abcd, - defg): - Baz = -{ ... } -``` - -If the expression covers multiple lines, if the first line of the expression -fits in the remaining space, it stays on the same line as the `=`, the rest of the -expression is not indented. If the first line does not fit, then it should start -on the next lines, and should be block indented. If the expression is a block -and the type or pattern cover multiple lines, then the opening brace should be -on a new line and not indented (this provides separation for the interior of the -block from the type), otherwise the opening brace follows the `=`. - -Examples: - -```rust -let foo = Foo { - f: abcd, - g: qwer, -}; - -let foo = - ALongName { - f: abcd, - g: qwer, - }; - -let foo: Type = { - an_expression(); - ... -}; - -let foo: - ALongType = -{ - an_expression(); - ... -}; - -let Foo { - f: abcd, - g: qwer, -}: Foo = Foo { - f: blimblimblim, - g: blamblamblam, -}; - -let Foo { - f: abcd, - g: qwer, -}: Foo = foo( - blimblimblim, - blamblamblam, -); -``` - - -### Macros in statement position - -A macro use in statement position should use parentheses or square brackets as -delimiters and should be terminated with a semi-colon. There should be no spaces -between the name, `!`, the delimiters, or the `;`. - -```rust -// A comment. -a_macro!(...); -``` - - -### Expressions in statement position - -There should be no space between the expression and the semi-colon. - -``` -; -``` - -All expressions in statement position should be terminated with a semi-colon, -unless they end with a block or are used as the value for a block. - -E.g., - -```rust -{ - an_expression(); - expr_as_value() -} - -return foo(); - -loop { - break; -} -``` - -Use a semi-colon where an expression has void type, even if it could be -propagated. E.g., - -```rust -fn foo() { ... } - -fn bar() { - foo(); -} -``` diff --git a/guide/types.md b/guide/types.md deleted file mode 100644 index ae456ef..0000000 --- a/guide/types.md +++ /dev/null @@ -1,58 +0,0 @@ -## Types and Bounds - -### Single line formatting - -* `[T]` no spaces -* `[T; expr]`, e.g., `[u32; 42]`, `[Vec; 10 * 2 + foo()]` (space after colon, no spaces around square brackets) -* `*const T`, `*mut T` (no space after `*`, space before type) -* `&'a T`, `&T`, `&'a mut T`, `&mut T` (no space after `&`, single spaces separating other words) -* `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keywords and sigils, and after commas, no trailing commas, no spaces around brackets) -* `!` should be treated like any other type name, `Name` -* `(A, B, C, D)` (spaces after commas, no spaces around parens, no trailing comma unless it is a one-tuple) -* ` as SomeTrait>::Foo::Bar` or `Foo::Bar` or `::Foo::Bar` (no spaces around `::` or angle brackets, single spaces around `as`) -* `Foo::Bar` (spaces after commas, no trailing comma, no spaces around angle brackets) -* `T + T + T` (single spaces between types, and `+`). -* `impl T + T + T` (single spaces between keyword, types, and `+`). - -Parentheses used in types should not be surrounded by whitespace, e.g., `(Foo)` - - -### Line breaks - -Avoid breaking lines in types where possible. Prefer breaking at outermost scope, e.g., prefer - -```rust -Foo< - Bar, - Baz, -> -``` - -to - -```rust -Foo> -``` - -`[T; expr]` may be broken after the `;` if necessary. - -Function types may be broken following the rules for function declarations. - -Generic types may be broken following the rules for generics. - -Types with `+` may be broken after any `+` using block indent and breaking before the `+`. When breaking such a type, all `+`s should be line broken, e.g., - -```rust -impl Clone - + Copy - + Debug - -Box< - Clone - + Copy - + Debug -> -``` diff --git a/text/0053-struct-union-declaration.md b/text/0053-struct-union-declaration.md deleted file mode 100644 index a0b714e..0000000 --- a/text/0053-struct-union-declaration.md +++ /dev/null @@ -1,78 +0,0 @@ -- Start Date: 2017-01-20 -- RFC Issue: #30 -- RFC PR: -- Implementation Issue: - -# Summary -[summary]: #summary - -Define the format for struct and union declarations. - - -# Details -[details]: #details - -Struct names follow on the same line as the `struct` keyword, with the opening brace on -the same line when it fits within the right margin. All struct fields are indented once and -end with a trailing comma. The closing brace is not indented and appears on its own line. - -```rust -struct Foo { - a: A, - b: B, -} -``` - -If and only if the type name does not fit within the right margin, it is pulled down to its -own line and indented again. - -```rust -struct Foo { - a: A, - long_name: - LongName, -} -``` - -The same guidelines are used for untagged unions declarations. - -```rust -union Foo { - a: A, - b: B, -} -``` - - -# Implementation -[implementation]: #implementation - -`rustfmt` currently formats structs correctly, except for the case where a long -type name needs to be indented onto its own line. - -Unions are currently not supported by `rustfmt:` -[rust-lang-nursery/rustfmt#1157](https://github.com/rust-lang-nursery/rustfmt/issues/1157) - - -# Rationale -[rationale]: #rationale - -Requiring a trailing comma on the last struct field has the following benefits: - -- Follows the principle to use a trailing comma when it is followed by a newline: - [#42](https://github.com/rust-lang-nursery/fmt-rfcs/issues/42) -- Avoids the need to add a comma when adding another field -- Avoids the need to delete a comma with deleting a field -- Allows easier copying of fields between different structs - - -# Alternatives -[alternatives]: #alternatives - -Some prefer to omit the trailing comma from the final struct field. - - -# Unresolved questions -[unresolved]: #unresolved-questions - -Unions have not been stabilized yet, and thus the syntax could possibly change. \ No newline at end of file