diff --git a/CHANGELOG.md b/CHANGELOG.md index 21d30756179..e35f0e48f81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added +- Add `use_field_init_shorthand` config option. - Add `reorder_modules` configuration option. ## [0.3.6] 2018-01-18 diff --git a/Configurations.md b/Configurations.md index 5a914a0d610..369e1ddfff7 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1781,6 +1781,48 @@ fn lorem() { } ``` +## `use_field_init_shorthand` + +Use field initialize shorthand if possible. + +- **Default value**: `false` +- **Possible values**: `true`, `false` +- **Stable**: No + +#### `false` (default): + +```rust +struct Foo { + x: u32, + y: u32, + z: u32, +} + +fn main() { + let x = 1; + let y = 2; + let z = 3; + let a = Foo { x: x, y: y, z: z }; +} +``` + +#### `true`: + +```rust +struct Foo { + x: u32, + y: u32, + z: u32, +} + +fn main() { + let x = 1; + let y = 2; + let z = 3; + let a = Foo { x, y, z }; +} +``` + ## `use_try_shorthand` Replace uses of the try! macro by the ? shorthand diff --git a/src/bin/rustfmt.rs b/src/bin/rustfmt.rs index 5a9119cdb11..214c02f95a5 100644 --- a/src/bin/rustfmt.rs +++ b/src/bin/rustfmt.rs @@ -453,7 +453,7 @@ fn determine_operation(matches: &Matches) -> FmtResult { return Ok(Operation::Stdin { input: buffer, - config_path: config_path, + config_path, }); } @@ -469,8 +469,8 @@ fn determine_operation(matches: &Matches) -> FmtResult { .collect(); Ok(Operation::Format { - files: files, - config_path: config_path, - minimal_config_path: minimal_config_path, + files, + config_path, + minimal_config_path, }) } diff --git a/src/closures.rs b/src/closures.rs index 1d8641339f0..61287543da9 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -254,7 +254,7 @@ fn rewrite_closure_fn_decl( }; let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: SeparatorTactic::Never, separator_place: SeparatorPlace::Back, diff --git a/src/comment.rs b/src/comment.rs index 1862dda3581..9c0322bcaeb 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -290,11 +290,11 @@ fn rewrite_comment_inner( let mut fmt = StringFormat { opener: "", closer: "", - line_start: line_start, + line_start, line_end: "", shape: Shape::legacy(max_chars, fmt_indent), trim_end: true, - config: config, + config, }; let line_breaks = count_newlines(orig.trim_right()); @@ -900,7 +900,7 @@ pub struct CommentCodeSlices<'a> { impl<'a> CommentCodeSlices<'a> { pub fn new(slice: &'a str) -> CommentCodeSlices<'a> { CommentCodeSlices { - slice: slice, + slice, last_slice_kind: CodeCharKind::Comment, last_slice_end: 0, } @@ -1024,7 +1024,7 @@ impl<'a> CommentReducer<'a> { let is_block = comment.starts_with("/*"); let comment = remove_comment_header(comment); CommentReducer { - is_block: is_block, + is_block, at_start_line: false, // There are no supplementary '*' on the first line iter: comment.chars(), } diff --git a/src/config.rs b/src/config.rs index 4b7f959b3de..c313f8e2aef 100644 --- a/src/config.rs +++ b/src/config.rs @@ -674,6 +674,7 @@ create_config! { condense_wildcard_suffixes: bool, false, false, "Replace strings of _ wildcards by a single .. \ in tuple patterns"; force_explicit_abi: bool, true, true, "Always print the abi for extern items"; + use_field_init_shorthand: bool, false, false, "Use field initialization shorthand if possible"; // Control options (changes the operation of rustfmt, rather than the formatting) write_mode: WriteMode, WriteMode::Overwrite, false, diff --git a/src/expr.rs b/src/expr.rs index e5c29e1c510..fb873ee26d3 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -449,7 +449,7 @@ pub fn rewrite_array( let ends_with_newline = tactic.ends_with_newline(context.config.indent_style()); let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: if trailing_comma { SeparatorTactic::Always @@ -470,7 +470,7 @@ pub fn rewrite_array( }, separator_place: SeparatorPlace::Back, shape: nested_shape, - ends_with_newline: ends_with_newline, + ends_with_newline, preserve_newline: false, config: context.config, }; @@ -787,35 +787,35 @@ impl<'a> ControlFlow<'a> { ) -> ControlFlow<'a> { ControlFlow { cond: Some(cond), - block: block, - else_block: else_block, + block, + else_block, label: None, - pat: pat, + pat, keyword: "if", matcher: match pat { Some(..) => "let", None => "", }, connector: " =", - allow_single_line: allow_single_line, - nested_if: nested_if, - span: span, + allow_single_line, + nested_if, + span, } } fn new_loop(block: &'a ast::Block, label: Option, span: Span) -> ControlFlow<'a> { ControlFlow { cond: None, - block: block, + block, else_block: None, - label: label, + label, pat: None, keyword: "loop", matcher: "", connector: "", allow_single_line: false, nested_if: false, - span: span, + span, } } @@ -828,10 +828,10 @@ impl<'a> ControlFlow<'a> { ) -> ControlFlow<'a> { ControlFlow { cond: Some(cond), - block: block, + block, else_block: None, - label: label, - pat: pat, + label, + pat, keyword: "while", matcher: match pat { Some(..) => "let", @@ -840,7 +840,7 @@ impl<'a> ControlFlow<'a> { connector: " =", allow_single_line: false, nested_if: false, - span: span, + span, } } @@ -853,16 +853,16 @@ impl<'a> ControlFlow<'a> { ) -> ControlFlow<'a> { ControlFlow { cond: Some(cond), - block: block, + block, else_block: None, - label: label, + label, pat: Some(pat), keyword: "for", matcher: "", connector: " in", allow_single_line: false, nested_if: false, - span: span, + span, } } @@ -1488,7 +1488,7 @@ fn rewrite_match_pattern( ) }; let fmt = ListFormatting { - tactic: tactic, + tactic, separator: " |", trailing_separator: SeparatorTactic::Never, separator_place: context.config.binop_separator(), @@ -1992,7 +1992,7 @@ where ); let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: if force_trailing_comma { SeparatorTactic::Always @@ -2569,9 +2569,13 @@ pub fn rewrite_field( if contains_skip(&field.attrs) { return Some(context.snippet(field.span()).to_owned()); } - let name = &field.ident.node.to_string(); + let mut attrs_str = field.attrs.rewrite(context, shape)?; + if !attrs_str.is_empty() { + attrs_str.push_str(&format!("\n{}", shape.indent.to_string(context.config))); + }; + let name = field.ident.node.to_string(); if field.is_shorthand { - Some(name.to_string()) + Some(attrs_str + &name) } else { let mut separator = String::from(struct_lit_field_separator(context.config)); for _ in 0..prefix_max_width.checked_sub(name.len()).unwrap_or(0) { @@ -2581,12 +2585,10 @@ pub fn rewrite_field( let expr_shape = shape.offset_left(overhead)?; let expr = field.expr.rewrite(context, expr_shape); - let mut attrs_str = field.attrs.rewrite(context, shape)?; - if !attrs_str.is_empty() { - attrs_str.push_str(&format!("\n{}", shape.indent.to_string(context.config))); - }; - match expr { + Some(ref e) if e.as_str() == name && context.config.use_field_init_shorthand() => { + Some(attrs_str + &name) + } Some(e) => Some(format!("{}{}{}{}", attrs_str, name, separator, e)), None => { let expr_offset = shape.indent.block_indent(context.config); @@ -2675,11 +2677,11 @@ where nested_shape.width, ); let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: SeparatorTactic::Never, separator_place: SeparatorPlace::Back, - shape: shape, + shape, ends_with_newline: false, preserve_newline: false, config: context.config, diff --git a/src/file_lines.rs b/src/file_lines.rs index 7f2273c6f69..028c631b1b9 100644 --- a/src/file_lines.rs +++ b/src/file_lines.rs @@ -34,7 +34,7 @@ impl<'a> From<&'a LineRange> for Range { impl Range { pub fn new(lo: usize, hi: usize) -> Range { - Range { lo: lo, hi: hi } + Range { lo, hi } } fn is_empty(self) -> bool { diff --git a/src/imports.rs b/src/imports.rs index c6997bd157f..3818fd21950 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -299,7 +299,7 @@ fn rewrite_imports( separator: "", trailing_separator: SeparatorTactic::Never, separator_place: SeparatorPlace::Back, - shape: shape, + shape, ends_with_newline: true, preserve_newline: false, config: context.config, @@ -552,7 +552,7 @@ fn rewrite_nested_use_tree( && tactic != DefinitiveListTactic::Horizontal; let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: if ends_with_newline { context.config.trailing_comma() @@ -561,7 +561,7 @@ fn rewrite_nested_use_tree( }, separator_place: SeparatorPlace::Back, shape: nested_shape, - ends_with_newline: ends_with_newline, + ends_with_newline, preserve_newline: true, config: context.config, }; diff --git a/src/issues.rs b/src/issues.rs index 6cd0586f3e4..2efd61a3d7d 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -90,8 +90,8 @@ impl BadIssueSeeker { todo_idx: 0, fixme_idx: 0, }, - report_todo: report_todo, - report_fixme: report_fixme, + report_todo, + report_fixme, } } @@ -169,8 +169,8 @@ impl BadIssueSeeker { } Seeking::Issue { - todo_idx: todo_idx, - fixme_idx: fixme_idx, + todo_idx, + fixme_idx, } } @@ -213,10 +213,7 @@ impl BadIssueSeeker { NumberPart::CloseParen => {} } - self.state = Seeking::Number { - part: part, - issue: issue, - }; + self.state = Seeking::Number { part, issue }; IssueClassification::None } diff --git a/src/items.rs b/src/items.rs index d0c5cf361c3..510c96681b8 100644 --- a/src/items.rs +++ b/src/items.rs @@ -138,7 +138,7 @@ impl<'a> Item<'a> { .iter() .map(|i| BodyElement::ForeignItem(i)) .collect(), - span: span, + span, } } } @@ -169,8 +169,8 @@ impl<'a> FnSig<'a> { vis: ast::Visibility, ) -> FnSig<'a> { FnSig { - decl: decl, - generics: generics, + decl, + generics, abi: abi::Abi::Rust, constness: ast::Constness::NotConst, defaultness: ast::Defaultness::Final, @@ -189,7 +189,7 @@ impl<'a> FnSig<'a> { defaultness: ast::Defaultness::Final, abi: method_sig.abi, decl: &*method_sig.decl, - generics: generics, + generics, visibility: ast::Visibility::Inherited, } } @@ -202,12 +202,12 @@ impl<'a> FnSig<'a> { ) -> FnSig<'a> { match *fn_kind { visit::FnKind::ItemFn(_, unsafety, constness, abi, visibility, _) => FnSig { - decl: decl, - generics: generics, - abi: abi, + decl, + generics, + abi, constness: constness.node, defaultness: defualtness, - unsafety: unsafety, + unsafety, visibility: visibility.clone(), }, visit::FnKind::Method(_, method_sig, vis, _) => { @@ -510,7 +510,7 @@ impl<'a> FmtVisitor<'a> { separator: ",", trailing_separator: self.config.trailing_comma(), separator_place: SeparatorPlace::Back, - shape: shape, + shape, ends_with_newline: true, preserve_newline: true, config: self.config, @@ -888,10 +888,10 @@ impl<'a> StructParts<'a> { _ => unreachable!(), }; StructParts { - prefix: prefix, + prefix, ident: item.ident, vis: &item.vis, - def: def, + def, generics: Some(generics), span: item.span, } @@ -1502,11 +1502,11 @@ impl<'a> StaticParts<'a> { _ => unreachable!(), }; StaticParts { - prefix: prefix, + prefix, vis: &item.vis, ident: item.ident, - ty: ty, - mutability: mutability, + ty, + mutability, expr_opt: Some(expr), defaultness: None, span: item.span, @@ -1522,7 +1522,7 @@ impl<'a> StaticParts<'a> { prefix: "const", vis: &ast::Visibility::Inherited, ident: ti.ident, - ty: ty, + ty, mutability: ast::Mutability::Immutable, expr_opt: expr_opt.as_ref(), defaultness: None, @@ -1539,7 +1539,7 @@ impl<'a> StaticParts<'a> { prefix: "const", vis: &ii.vis, ident: ii.ident, - ty: ty, + ty, mutability: ast::Mutability::Immutable, expr_opt: Some(expr), defaultness: Some(ii.defaultness), @@ -1811,7 +1811,7 @@ fn rewrite_fn_base( let one_line_budget = context.budget(used_width + overhead); let shape = Shape { width: one_line_budget, - indent: indent, + indent, offset: used_width, }; let fd = fn_sig.decl; @@ -2078,8 +2078,8 @@ struct WhereClauseOption { impl WhereClauseOption { pub fn new(suppress_comma: bool, snuggle: bool) -> WhereClauseOption { WhereClauseOption { - suppress_comma: suppress_comma, - snuggle: snuggle, + suppress_comma, + snuggle, compress_where: false, } } @@ -2226,7 +2226,7 @@ fn rewrite_args( debug!("rewrite_args: budget: {}, tactic: {:?}", budget, tactic); let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: if variadic { SeparatorTactic::Never @@ -2397,7 +2397,7 @@ where one_line_budget, ); let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: if context.config.indent_style() == IndentStyle::Visual { SeparatorTactic::Never @@ -2405,7 +2405,7 @@ where context.config.trailing_comma() }, separator_place: SeparatorPlace::Back, - shape: shape, + shape, ends_with_newline: tactic.ends_with_newline(context.config.indent_style()), preserve_newline: true, config: context.config, @@ -2630,7 +2630,7 @@ fn rewrite_where_clause( } let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: comma_tactic, separator_place: SeparatorPlace::Back, diff --git a/src/lib.rs b/src/lib.rs index 73cbd7527ba..fb2f5ca5fa6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -449,7 +449,7 @@ fn format_lines( line: cur_line, kind: error_kind, is_comment: kind.is_comment(), - is_string: is_string, + is_string, line_buffer: line_buffer.clone(), }); } diff --git a/src/lists.rs b/src/lists.rs index 193cd4f3c32..aa1e0b430ef 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -690,15 +690,15 @@ where }; ListItem { - pre_comment: pre_comment, - pre_comment_style: pre_comment_style, + pre_comment, + pre_comment_style, item: if self.inner.peek().is_none() && self.leave_last { None } else { (self.get_item_string)(&item) }, - post_comment: post_comment, - new_lines: new_lines, + post_comment, + new_lines, } }) } @@ -724,16 +724,16 @@ where F3: Fn(&T) -> Option, { ListItems { - codemap: codemap, + codemap, inner: inner.peekable(), - get_lo: get_lo, - get_hi: get_hi, - get_item_string: get_item_string, - prev_span_end: prev_span_end, - next_span_start: next_span_start, - terminator: terminator, - separator: separator, - leave_last: leave_last, + get_lo, + get_hi, + get_item_string, + prev_span_end, + next_span_start, + terminator, + separator, + leave_last, } } @@ -841,7 +841,7 @@ pub fn struct_lit_formatting<'a>( let ends_with_newline = context.config.indent_style() != IndentStyle::Visual && tactic == DefinitiveListTactic::Vertical; ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: if force_no_trailing_comma { SeparatorTactic::Never @@ -849,8 +849,8 @@ pub fn struct_lit_formatting<'a>( context.config.trailing_comma() }, separator_place: SeparatorPlace::Back, - shape: shape, - ends_with_newline: ends_with_newline, + shape, + ends_with_newline, preserve_newline: true, config: context.config, } diff --git a/src/rustfmt_diff.rs b/src/rustfmt_diff.rs index d563e6eee3c..1a2f570f89e 100644 --- a/src/rustfmt_diff.rs +++ b/src/rustfmt_diff.rs @@ -31,7 +31,7 @@ pub struct Mismatch { impl Mismatch { fn new(line_number: u32) -> Mismatch { Mismatch { - line_number: line_number, + line_number, lines: Vec::new(), } } diff --git a/src/shape.rs b/src/shape.rs index fffbe2b9913..8fe2e2b18c0 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -29,8 +29,8 @@ const INDENT_BUFFER: &str = impl Indent { pub fn new(block_indent: usize, alignment: usize) -> Indent { Indent { - block_indent: block_indent, - alignment: alignment, + block_indent, + alignment, } } @@ -161,8 +161,8 @@ impl Shape { // |<--->| width pub fn legacy(width: usize, indent: Indent) -> Shape { Shape { - width: width, - indent: indent, + width, + indent, offset: indent.alignment, } } @@ -170,7 +170,7 @@ impl Shape { pub fn indented(indent: Indent, config: &Config) -> Shape { Shape { width: config.max_width().checked_sub(indent.width()).unwrap_or(0), - indent: indent, + indent, offset: indent.alignment, } } @@ -187,9 +187,9 @@ impl Shape { pub fn offset(width: usize, indent: Indent, offset: usize) -> Shape { Shape { - width: width, - indent: indent, - offset: offset, + width, + indent, + offset, } } diff --git a/src/string.rs b/src/string.rs index 43b1ccbcb93..2386d90ec8a 100644 --- a/src/string.rs +++ b/src/string.rs @@ -36,9 +36,9 @@ impl<'a> StringFormat<'a> { closer: "\"", line_start: " ", line_end: "\\", - shape: shape, + shape, trim_end: false, - config: config, + config, } } } diff --git a/src/types.rs b/src/types.rs index 588d9100fe6..a7472567a81 100644 --- a/src/types.rs +++ b/src/types.rs @@ -352,7 +352,7 @@ where ); let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: if !context.use_block_indent() || variadic { SeparatorTactic::Never diff --git a/src/vertical.rs b/src/vertical.rs index e56410202eb..2ccb5d81339 100644 --- a/src/vertical.rs +++ b/src/vertical.rs @@ -247,7 +247,7 @@ fn rewrite_aligned_items_inner( ); let fmt = ListFormatting { - tactic: tactic, + tactic, separator: ",", trailing_separator: context.config.trailing_comma(), separator_place: SeparatorPlace::Back, diff --git a/src/visitor.rs b/src/visitor.rs index 8063057e9e9..75e7c0be254 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -591,14 +591,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { snippet_provider: &'a SnippetProvider, ) -> FmtVisitor<'a> { FmtVisitor { - parse_session: parse_session, + parse_session, codemap: parse_session.codemap(), buffer: String::with_capacity(snippet_provider.big_snippet.len() * 2), last_pos: BytePos(0), block_indent: Indent::empty(), - config: config, + config, is_if_else_block: false, - snippet_provider: snippet_provider, + snippet_provider, line_number: 0, skipped_range: vec![], } diff --git a/tests/source/configs/use_field_init_shorthand/false.rs b/tests/source/configs/use_field_init_shorthand/false.rs new file mode 100644 index 00000000000..16ce740f1b9 --- /dev/null +++ b/tests/source/configs/use_field_init_shorthand/false.rs @@ -0,0 +1,19 @@ +// rustfmt-use_field_init_shorthand: false +// Use field initialization shorthand if possible. + +fn main() { + let a = Foo { + x: x, + y: y, + z: z, + }; + + let b = Bar { + x: x, + y: y, + #[attr] + z: z, + #[rustfmt_skip] + skipped: skipped, + }; +} diff --git a/tests/source/configs/use_field_init_shorthand/true.rs b/tests/source/configs/use_field_init_shorthand/true.rs new file mode 100644 index 00000000000..1e36c6cff35 --- /dev/null +++ b/tests/source/configs/use_field_init_shorthand/true.rs @@ -0,0 +1,19 @@ +// rustfmt-use_field_init_shorthand: true +// Use field initialization shorthand if possible. + +fn main() { + let a = Foo { + x: x, + y: y, + z: z, + }; + + let b = Bar { + x: x, + y: y, + #[attr] + z: z, + #[rustfmt_skip] + skipped: skipped, + }; +} diff --git a/tests/target/configs/use_field_init_shorthand/false.rs b/tests/target/configs/use_field_init_shorthand/false.rs new file mode 100644 index 00000000000..dcebe0b6f1d --- /dev/null +++ b/tests/target/configs/use_field_init_shorthand/false.rs @@ -0,0 +1,15 @@ +// rustfmt-use_field_init_shorthand: false +// Use field initialization shorthand if possible. + +fn main() { + let a = Foo { x: x, y: y, z: z }; + + let b = Bar { + x: x, + y: y, + #[attr] + z: z, + #[rustfmt_skip] + skipped: skipped, + }; +} diff --git a/tests/target/configs/use_field_init_shorthand/true.rs b/tests/target/configs/use_field_init_shorthand/true.rs new file mode 100644 index 00000000000..ad78093ee8e --- /dev/null +++ b/tests/target/configs/use_field_init_shorthand/true.rs @@ -0,0 +1,15 @@ +// rustfmt-use_field_init_shorthand: true +// Use field initialization shorthand if possible. + +fn main() { + let a = Foo { x, y, z }; + + let b = Bar { + x, + y, + #[attr] + z, + #[rustfmt_skip] + skipped: skipped, + }; +} diff --git a/tests/target/impl.rs b/tests/target/impl.rs index 99922d406f4..5895c74bcc9 100644 --- a/tests/target/impl.rs +++ b/tests/target/impl.rs @@ -13,7 +13,7 @@ where pub fn new(value: V) -> Self { Test { cloned_value: value.clone(), - value: value, + value, } } }