diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md index b8aa64ba14f6f..29204603e58d3 100644 --- a/src/doc/style-guide/src/README.md +++ b/src/doc/style-guide/src/README.md @@ -40,7 +40,6 @@ options. * Each level of indentation must be four 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 may choose to make some of these configurable. #### Block indent @@ -63,7 +62,8 @@ example) and less rightward drift. ### Trailing commas -Lists should have a trailing comma when followed by a newline: +In comma-separated lists of any kind, use a trailing comma when followed by a +newline: ```rust function_call( @@ -99,8 +99,6 @@ fn bar() {} fn baz() {} ``` -Formatting tools may wish to make the bounds on blank lines configurable. - ### [Module-level items](items.md) ### [Statements](statements.md) ### [Expressions](expressions.md) @@ -114,17 +112,17 @@ 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 line comments, put 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. +When using single-line block comments, put a single space after the opening +sigil and before the closing sigil. For multi-line block comments, put a +newline after the opening sigil, and a newline 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: +Prefer to put a comment on its own line. Where a comment follows code, put a +single space before it. Where a block comment appears inline, use surrounding +whitespace as if it were an identifier or keyword. Do not include trailing +whitespace after a comment or at the end of any line in a multi-line comment. +Examples: ```rust // A comment on an item. @@ -173,7 +171,7 @@ 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. +Put doc comments before attributes. ### Attributes @@ -198,18 +196,20 @@ struct CRepr { } ``` -For attributes with an equal sign, there should be a single space before and -after the `=`, e.g., `#[foo = 42]`. +For attributes with an equal sign, put 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;`. +the derived names must generally be preserved for correctness: +`#[derive(Foo)] #[derive(Bar)] struct Baz;` must be formatted to +`#[derive(Foo, Bar)] 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: +In many places in this guide we specify formatting that depends on a code +construct being *small*. For example, single-line vs multi-line struct +literals: ```rust // Normal formatting @@ -218,7 +218,7 @@ Foo { f2: another_expression(), } -// *small* formatting +// "small" formatting Foo { f1, f2 } ``` @@ -231,10 +231,6 @@ 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) diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index 41a9eb82cb5af..0aed8763a0628 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -2,10 +2,13 @@ ### 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: +A block expression must have a newline after the initial `{` and before the +terminal `}`, unless it qualifies to be written as a single line based on +another style rule. + +A keyword before the block (such as `unsafe` or `async`) must be on the same +line as the opening brace, with a single space between the keyword and the +opening brace. Indent the contents of the block. ```rust fn block_as_stmt() { @@ -40,7 +43,7 @@ fn unsafe_block_as_stmt() { } ``` -If a block has an attribute, it should be on its own line: +If a block has an attribute, put it on its own line before the block: ```rust fn block_as_stmt() { @@ -54,18 +57,18 @@ fn block_as_stmt() { } ``` -Avoid writing comments on the same line as the braces. +Avoid writing comments on the same lines as either of the braces. -An empty block should be written as `{}`. +Write an empty block as `{}`. -A block may be written on a single line if: +Write a block on a single line if: * it is either used in expression position (not statement position) or is an unsafe block in statement position -* contains a single-line expression and no statements -* contains no comments +* it contains a single-line expression and no statements +* it contains no comments -A single line block should have spaces after the opening brace and before the +For a single-line block, put spaces after the opening brace and before the closing brace. Examples: @@ -117,9 +120,9 @@ fn main() { ### 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. +by a keyword such as `move`); put a space between the second `|` and the +expression of the closure. Between the `|`s, use function definition syntax, +but elide types where possible. Use closures without the enclosing `{}`, if possible. Add the `{}` when you have a return type, when there are statements, there are comments in the body, or the @@ -155,13 +158,14 @@ move |arg1: i32, arg2: i32| -> i32 { ### Struct literals -If a struct literal is *small* it may be formatted on a single line. If not, -each field should be on it's 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. +If a struct literal is *small*, format it on a single line, and do not use a +trailing comma. If not, split it across multiple lines, with each field on its +own block-indented line, and use a trailing comma. + +For each `field: value` entry, put 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. +Put a space before the opening brace. In the single-line form, put spaces after +the opening brace and before the closing brace. ```rust Foo { field1, field2: 0 } @@ -172,7 +176,7 @@ let f = Foo { ``` Functional record update syntax is treated like a field, but it must never have -a trailing comma. There should be no space after `..`. +a trailing comma. Do not put a space after `..`. let f = Foo { field1, @@ -182,9 +186,13 @@ let f = Foo { ### 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. +Use a single-line form where possible. Do not put spaces between the opening +parenthesis and the first element, or between the last element and the closing +parenthesis. Separate elements with a comma followed by a space. + +Where a single-line form is not possible, write the tuple across +multiple lines, with each element of the tuple on its own block-indented line, +and use a trailing comma. ```rust (a, b, c) @@ -198,14 +206,23 @@ let x = ( ### 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)`. +Do not put space between the identifier and the opening parenthesis. Otherwise, +follow the rules for tuple literals: + +```rust +Foo(a, b, c) + +let x = Foo( + a_long_expr, + another_very_long_expr, +); +``` ### 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., +name of the enum as a qualifying name, unless the enum is in the prelude: ```rust Foo::Bar(a, b) @@ -219,24 +236,29 @@ 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: +Write small array literals on a single line. Do not put spaces between the opening +square bracket and the first element, or between the last element and the closing +square bracket. Separate elements with a comma followed by a space. + +If using the repeating initializer, put a space after the semicolon +only. + +Apply the same rules if using `vec!` or similar array-like macros; always use +square brackets with such macros. Examples: ```rust fn main() { - [1, 2, 3]; - vec![a, b, c, d]; + let x = [1, 2, 3]; + let y = 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: +For arrays that have to be broken across lines, if using the repeating +initializer, break after the `;`, not before. Otherwise, follow the rules below +for function calls. In any case, block-indent the contents of the initializer, +and put line breaks after the opening square bracket and before the closing +square bracket: ```rust fn main() { @@ -255,11 +277,12 @@ fn main() { ### 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. +Don't put spaces around the square brackets. Avoid breaking lines if possible. +Never break a line between the target expression and the opening square +bracket. If the indexing expression must be broken onto a subsequent line, or +spans multiple lines itself, then block-indent the indexing expression, and put +newlines after the opening square bracket and before the closing square +bracket: Examples: @@ -291,7 +314,7 @@ 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, unless necessary (e.g. to avoid an unnecessarily expensive operation). -Use parentheses liberally, do not necessarily elide them due to precedence. +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. @@ -353,10 +376,10 @@ 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 it's 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., +or any argument or the callee is multi-line, then format the call across +multiple lines. In this case, put each argument on its own block-indented line, +break after the opening parenthesis and before the closing parenthesis, +and use a trailing comma: ```rust a_function_call( @@ -379,17 +402,18 @@ x.foo().bar().baz(x, y, z); ### Macro uses -Macros which can be parsed like other constructs should be formatted like those +If a macro can be parsed like other constructs, format it 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. +function call (ignoring the `!`), so format it using 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, +For macros which take a format string, if all other arguments are *small*, +format the arguments before the format string on a single line if they fit, and +format the arguments after the format string on a single line if they fit, with +the format string on its own line. If the arguments are not small or do not +fit, put each on its own line as with a function. For example: ```rust println!( @@ -416,13 +440,13 @@ 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?`. +A chain is a sequence of field accesses, method calls, and/or uses of 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., +Format the chain on one line if it is "small" and otherwise possible to do so. +If formatting on multiple lines, put each field access or method call in the +chain on its own line, with the line-break before the `.` and after any `?`. +Block-indent each subsequent line: ```rust let foo = bar @@ -431,13 +455,16 @@ let foo = bar ``` 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., +less than or equal to the indentation of the second line, then combine the +first and second lines if they fit. Apply this rule recursively. ```rust x.baz? .qux() +x.y.z + .qux() + let foo = x .baz? .qux(); @@ -489,13 +516,13 @@ self.pre_comment.as_ref().map_or( 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. +Put the keyword, any initial clauses, and the opening brace of the block all on +a single line, if they fit. Apply the usual rules for [block +formatting](#blocks) 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: +If there is an `else` component, then put the closing brace, `else`, any +following clause, and the opening brace all on the same line, with a single +space before and after the `else` keyword: ```rust if ... { @@ -513,10 +540,10 @@ if let ... { } ``` -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: +If the control line needs to be broken, prefer to break before the `=` in `* +let` expressions and before `in` in a `for` expression; block-indent the +following line. If the control line is broken for any reason, put the opening +brace on its own line, not indented. Examples: ```rust while let Some(foo) @@ -539,10 +566,10 @@ if a_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 +Where the initial clause spans multiple lines 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 put the opening brace of the block on the same line with a preceding space. For example: ```rust @@ -558,9 +585,9 @@ if !self.config.file_lines().intersects( #### 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: +Put 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*: ```rust let y = if x { 0 } else { 1 }; @@ -582,9 +609,9 @@ if x { ### 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: +Prefer not to line-break inside the discriminant expression. Always break after +the opening brace and before the closing brace. Block-indent the match arms +once: ```rust match foo { @@ -598,7 +625,7 @@ let x = match foo.bar.baz() { 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., +Never start a match arm pattern with `|`: ```rust match foo { @@ -608,14 +635,13 @@ match foo { | a_very_long_pattern | another_pattern | yet_another_pattern - | a_forth_pattern => { + | a_fourth_pattern => { ... } } ``` -Prefer - +Prefer: ```rust match foo { @@ -623,7 +649,7 @@ match foo { a_very_long_pattern | another_pattern | yet_another_pattern - | a_forth_pattern => { + | a_fourth_pattern => { ... } } @@ -633,11 +659,11 @@ 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. +If the right-hand side consists of multiple statements, or has line comments, +or the start of the line does not fit on the same line as the left-hand side, +use a block. -The body of a block arm should be block indented once. +Block-indent the body of a block arm. Examples: @@ -662,8 +688,8 @@ match foo { ``` 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 right-hand side. If -not, then it must be in a block. Example, +expression, start it on the same line as the left-hand side. If not, then it +must be in a block. Example: ```rust match foo { @@ -687,8 +713,8 @@ match foo { #### 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. +If using a block form on the right-hand side of a match arm makes it possible +to avoid breaking on the left-hand side, do that: ```rust // Assuming the following line does not fit in the max width @@ -720,7 +746,7 @@ body on a new line: 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: +clause, use the above form: ```rust a_very_long_pattern @@ -740,7 +766,7 @@ clause, then you must use the above form: ``` 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., +not put the `if` clause on a new line. E.g., ```rust Token::Dimension { @@ -753,8 +779,8 @@ not put the `if` clause on a newline. E.g., ``` If every clause in a pattern is *small*, but the whole pattern 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 `|`: +one line, then format the pattern across multiple lines with as many clauses +per line as possible. Again, break before a `|`: ```rust foo | bar | baz @@ -783,8 +809,8 @@ E.g., `&&Some(foo)` matches, `Foo(4, Bar)` does not. ### 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 +across multiple-lines, format the outer call as if it were a single-line call, +if the result fits. Apply the same combining behaviour 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., @@ -814,13 +840,12 @@ let arr = [combinable( )]; ``` -Such behaviour should extend recursively, however, tools may choose to limit the -depth of nesting. +Apply this behavior recursively. -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: +For a function with multiple arguments, if the last argument is a multi-line +closure with an explicit block, there are no other closure arguments, and all +the arguments and the first line of the closure fit on the first line, use the +same combining behavior: ```rust foo(first_arg, x, |param| { @@ -835,16 +860,17 @@ foo(first_arg, x, |param| { 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: +broken within the range, 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)`. +For the sake of indicating precedence, if either bound is a compound +expression, use parentheses around it, e.g., `..(x + 1)`, `(x.f)..(x.f.len())`, +or `0..(x - 10)`. ### Hexadecimal literals @@ -852,11 +878,8 @@ compound expression, then use parentheses around it, e.g., `..(x + 1)`, 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. +Format patterns like their corresponding expressions. See the section on +`match` for additional formatting for patterns in match arms. diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index de31e8a8799b3..6e5ea335e6ab2 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -9,19 +9,17 @@ an item appears at module level or within another item. 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. +must come before other items. Put imports before module declarations. Sort each +alphabetically, except that `self` and `super` must come before any other +names. +Don't automatically move module declarations annotated with `#[macro_use]`, +since that might change semantics. ### Function definitions In Rust, people often find functions by searching for `fn [function-name]`, so -the formatting of function definitions shold enable this. +the formatting of function definitions must enable this. The proper ordering and spacing is: @@ -83,9 +81,9 @@ enum FooBar { } ``` -If a struct variant is [*small*](index.html#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: +If a struct variant is [*small*](index.html#small-items), format it 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 { @@ -94,9 +92,9 @@ enum FooBar { ``` 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. +multiple lines, use the multi-line formatting 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 @@ -143,9 +141,9 @@ union Foo { ### 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 semicolon: +Put the whole struct on one line if possible. Separate types within the +parentheses using a comma and space. Don't use a trailing comma for a +single-line tuple struct. Don't put spaces around the parentheses or semicolon: ```rust pub struct Foo(String, u8); @@ -154,9 +152,11 @@ 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: +For more than a few fields (in particular if the tuple struct does not fit on +one line), prefer a proper struct with named fields. + +For a multi-line tuple struct, block-format the fields with a field on each +line and a trailing comma: ```rust pub struct Foo( @@ -168,9 +168,9 @@ pub struct Foo( ### 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: +Use block-indent for trait items. If there are no items, format the trait (including its `{}`) +on a single line. Otherwise, break after the opening brace and before +the closing brace: ```rust trait Foo {} @@ -180,8 +180,8 @@ 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., +If the trait has bounds, put a space after the colon but not before, +and put spaces around each `+`, e.g., ```rust trait Foo: Debug + Bar {} @@ -207,9 +207,9 @@ pub trait IndexRanges: ### 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: +Use block-indent for impl items. If there are no items, format the impl +(including its `{}`) on a single line. Otherwise, break after the opening brace +and before the closing brace: ```rust impl Foo {} @@ -267,12 +267,12 @@ macro_rules! foo { 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. +large enough to require line-breaking, prefer 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. +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. +Put a space after each comma. Do not use a trailing comma for a single-line +generics clause. ```rust fn foo(x: Vec, y: Vec) ... @@ -280,10 +280,9 @@ 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. +If the generics clause must be formatted across multiple lines, put each +parameter on its own block-indented line, break after the opening `<` and +before the closing `>`, and use a trailing comma. ```rust fn foo< @@ -292,8 +291,7 @@ fn foo< >(x: Vec, y: Vec) ... ``` -If an associated type is bound in a generic type, then there should be spaces on -either side of the `=`: +If an associated type is bound in a generic type, put spaces around the `=`: ```rust > @@ -306,12 +304,14 @@ Prefer to use single-letter names for generic parameters. 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 +If immediately following a closing bracket of any kind, write the keyword +`where` on the same line, with a space before it. + +Otherwise, put `where` on a new line at the same indentation level. Put each +component of a `where` clause on its own line, block-indented. Use 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: +is followed by a block (or assignment), start that block on a new line. +Examples: ```rust fn function(args) @@ -355,12 +355,12 @@ where = Bar; ``` -If a `where` clause is very short, we recommend using an inline bound on the -type parameter. +If a `where` clause is very short, prefer 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., +If a component of a `where` clause does not fit and contains `+`, break it +before each `+` and block-indent the continuation lines. Put each bound on its +own line. E.g., ```rust impl IndexRanges for T @@ -369,40 +369,14 @@ where + 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 -} + + Index, Output = Self::Output> + + Index, ``` - ### 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: +Keep type aliases on one line when they fit. If necessary to break the line, do +so after the `=`, and block-indent the right-hand side: ```rust pub type Foo = Bar; @@ -427,9 +401,8 @@ where ### 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: +Format associated types like type aliases. Where an associated type has a +bound, put a space after the colon but not before: ```rust pub type Foo: Bar; @@ -438,15 +411,14 @@ 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 +When writing extern items (such as `extern "C" fn`), always specify 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. +Format imports on one line where possible. Don't put spaces around braces. ```rust use a::b::c; @@ -458,7 +430,7 @@ 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). +should not split imports by default. 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 @@ -521,14 +493,12 @@ example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g., #### Normalisation -Tools must make the following normalisations: +Tools must make the following normalisations, recursively: * `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). diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md index a5cd6da10616d..8c8f893fbe904 100644 --- a/src/doc/style-guide/src/statements.md +++ b/src/doc/style-guide/src/statements.md @@ -2,8 +2,8 @@ ### Let statements -There should be spaces after the `:` and on both sides of the `=` (if they are -present). No space before the semicolon. +Put a space after the `:` and on both sides of the `=` (if they are present). +Don't put a space before the semicolon. ```rust // A comment. @@ -14,19 +14,19 @@ 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. +If possible, format the declaration on a single line. If not possible, then try +splitting after the `=`, if the declaration fits on two lines. Block-indent the +expression. ```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). +If the first line still does not fit on a single line, split after the `:`, and +use block indentation. If the type requires multiple lines, even after +line-breaking after the `:`, then place the first line on the same line as the +`:`, subject to the [combining rules](expressions.html#combinable-expressions). ```rust @@ -51,12 +51,12 @@ let (abcd, ``` 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 `=`. +fits in the remaining space, it stays on the same line as the `=`, and the rest +of the expression is not further indented. If the first line does not fit, then +put the expression on subsequent lines, block indented. If the expression is a +block and the type or pattern cover multiple lines, put the opening brace 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: @@ -108,8 +108,8 @@ In this case, always apply the same formatting rules to the components preceding the `else` block (i.e. the `let pattern: Type = initializer_expr` portion) as described [for other let statements](#let-statements). -The entire let-else statement may be formatted on a single line if all the -following are true: +Format the entire let-else statement on a single line if all the following are +true: * the entire statement is *short* * the `else` block contains only a single-line expression and no statements @@ -120,9 +120,6 @@ following are true: let Some(1) = opt else { return }; ``` -Formatters may allow users to configure the value of the threshold -used to determine whether a let-else statement is *short*. - Otherwise, the let-else statement requires some line breaks. If breaking a let-else statement across multiple lines, never break between the @@ -157,9 +154,9 @@ before the `else`. }; ``` -If the initializer expression is multi-line, the `else` keyword and opening -brace of the block (i.e. `else {`) should be put on the same line as the end of -the initializer expression, with a space between them, if and only if all the +If the initializer expression is multi-line, put the `else` keyword and opening +brace of the block (i.e. `else {`) on the same line as the end of the +initializer expression, with a space between them, if and only if all the following are true: * The initializer expression ends with one or more closing @@ -182,9 +179,9 @@ let Some(x) = y.foo( } ``` -Otherwise, the `else` keyword and opening brace should be placed on the next -line after the end of the initializer expression, and the `else` keyword should -have the same indentation level as the `let` keyword. +Otherwise, put the `else` keyword and opening brace on the next line after the +end of the initializer expression, with the `else` keyword at the same +indentation level as the `let` keyword. For example: @@ -236,9 +233,9 @@ fn main() { ### Macros in statement position -A macro use in statement position should use parentheses or square brackets as -delimiters and should be terminated with a semicolon. There should be no spaces -between the name, `!`, the delimiters, or the `;`. +For a macro use in statement position, use parentheses or square brackets as +delimiters, and terminate it with a semicolon. Do not put spaces around the +name, `!`, the delimiters, or the `;`. ```rust // A comment. @@ -248,14 +245,14 @@ a_macro!(...); ### Expressions in statement position -There should be no space between the expression and the semicolon. +Do not put space between the expression and the semicolon. ``` ; ``` -All expressions in statement position should be terminated with a semicolon, -unless they end with a block or are used as the value for a block. +Terminate all expressions in statement position with a semicolon, unless they +end with a block or are used as the value for a block. E.g., diff --git a/src/doc/style-guide/src/types.md b/src/doc/style-guide/src/types.md index ae456ef21c8d4..15b001d4f2ea5 100644 --- a/src/doc/style-guide/src/types.md +++ b/src/doc/style-guide/src/types.md @@ -7,14 +7,14 @@ * `*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` +* `!` gets 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)` +Do not put space around parentheses used in types, e.g., `(Foo)` ### Line breaks @@ -37,13 +37,17 @@ Foo> ``` -`[T; expr]` may be broken after the `;` if necessary. +If a type requires line-breaks in order to fit, this section outlines where to +break such types if necessary. -Function types may be broken following the rules for function declarations. +Break `[T; expr]` after the `;` if necessary. -Generic types may be broken following the rules for generics. +Break function types following the rules for function declarations. -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., +Break generic types following the rules for generics. + +Break types with `+` by breaking before the `+` and block-indenting the +subsequent lines. When breaking such a type, break before *every* `+`: ```rust impl Clone