From d354389e8e1ae1272fc8a9a81371d93e715d7037 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 31 Mar 2026 13:45:18 -0700 Subject: [PATCH 01/17] Setup regression test for issue 4053 --- tests/source/issue-4053.rs | 14 ++++++++++++++ tests/target/issue-4053.rs | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 tests/source/issue-4053.rs create mode 100644 tests/target/issue-4053.rs diff --git a/tests/source/issue-4053.rs b/tests/source/issue-4053.rs new file mode 100644 index 00000000000..1c3df00255b --- /dev/null +++ b/tests/source/issue-4053.rs @@ -0,0 +1,14 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[5,5]},{"file":"tests/source/issue-4053.rs","range":[11,11]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .unwrap(); +} + +fn match_expr(x: i32) { + match x { + 0 => {}, + _ => {}, + }; +} diff --git a/tests/target/issue-4053.rs b/tests/target/issue-4053.rs new file mode 100644 index 00000000000..a6d9c996f32 --- /dev/null +++ b/tests/target/issue-4053.rs @@ -0,0 +1,14 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[5,5]},{"file":"tests/source/issue-4053.rs","range":[11,11]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .unwrap(); +} + +fn match_expr(x: i32) { + match x { + 0 => {}, + _ => {}, + }; +} From eccd87b7fe5e376be661272a7cee279a66354f51 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 31 Mar 2026 15:04:10 -0700 Subject: [PATCH 02/17] Flesh out method chain test --- tests/source/issue-4053.rs | 12 +++++++++++- tests/target/issue-4053.rs | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/source/issue-4053.rs b/tests/source/issue-4053.rs index 1c3df00255b..f81696c263d 100644 --- a/tests/source/issue-4053.rs +++ b/tests/source/issue-4053.rs @@ -1,9 +1,19 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[5,5]},{"file":"tests/source/issue-4053.rs","range":[11,11]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[5,5]},{"file":"tests/source/issue-4053.rs","range":[13,13]},{"file":"tests/source/issue-4053.rs","range":[21,21]}] fn method_chain(val: Option) { let _ = val .map(|val| val) .unwrap(); + + let _ = val + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); } fn match_expr(x: i32) { diff --git a/tests/target/issue-4053.rs b/tests/target/issue-4053.rs index a6d9c996f32..fe278c31c86 100644 --- a/tests/target/issue-4053.rs +++ b/tests/target/issue-4053.rs @@ -1,9 +1,19 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[5,5]},{"file":"tests/source/issue-4053.rs","range":[11,11]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[5,5]},{"file":"tests/source/issue-4053.rs","range":[13,13]},{"file":"tests/source/issue-4053.rs","range":[21,21]}] fn method_chain(val: Option) { let _ = val .map(|val| val) .unwrap(); + + let _ = val + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); } fn match_expr(x: i32) { From 44ec2c49fe98ed8f1ff03e15b9267139a11738e2 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 31 Mar 2026 15:23:43 -0700 Subject: [PATCH 03/17] Add more method chain test cases --- tests/source/issue-4053.rs | 17 ++++++++++++++++- tests/target/issue-4053.rs | 19 ++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/tests/source/issue-4053.rs b/tests/source/issue-4053.rs index f81696c263d..118106bbcce 100644 --- a/tests/source/issue-4053.rs +++ b/tests/source/issue-4053.rs @@ -1,10 +1,14 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[5,5]},{"file":"tests/source/issue-4053.rs","range":[13,13]},{"file":"tests/source/issue-4053.rs","range":[21,21]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[8,8]},{"file":"tests/source/issue-4053.rs","range":[17,17]},{"file":"tests/source/issue-4053.rs","range":[23,23]},{"file":"tests/source/issue-4053.rs","range":[36,36]}] fn method_chain(val: Option) { + // Format one line of a short expression. If we were formatting the whole + // expression we would put it all on one line, so we need to handle it + // differently if we're formatting just one part of the expression. let _ = val .map(|val| val) .unwrap(); + // Format one method call in a large method chain. let _ = val .map(|val| val) .map(|val| val).map(|val| val) @@ -14,6 +18,17 @@ fn method_chain(val: Option) { .map(|val| val) .map(|val| val) .unwrap(); + + // Format the first part of a large method chain. + let _ = val.map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); } fn match_expr(x: i32) { diff --git a/tests/target/issue-4053.rs b/tests/target/issue-4053.rs index fe278c31c86..8b2cb5209e2 100644 --- a/tests/target/issue-4053.rs +++ b/tests/target/issue-4053.rs @@ -1,10 +1,14 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[5,5]},{"file":"tests/source/issue-4053.rs","range":[13,13]},{"file":"tests/source/issue-4053.rs","range":[21,21]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[8,8]},{"file":"tests/source/issue-4053.rs","range":[17,17]},{"file":"tests/source/issue-4053.rs","range":[23,23]},{"file":"tests/source/issue-4053.rs","range":[36,36]}] fn method_chain(val: Option) { + // Format one line of a short expression. If we were formatting the whole + // expression we would put it all on one line, so we need to handle it + // differently if we're formatting just one part of the expression. let _ = val .map(|val| val) .unwrap(); + // Format one method call in a large method chain. let _ = val .map(|val| val) .map(|val| val).map(|val| val) @@ -14,6 +18,19 @@ fn method_chain(val: Option) { .map(|val| val) .map(|val| val) .unwrap(); + + // Format the first part of a large method chain. + let _ = val + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); } fn match_expr(x: i32) { From 2b23f1632396d0b097580d22817ab343b9fbd1bf Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 31 Mar 2026 15:54:05 -0700 Subject: [PATCH 04/17] Split up tests and add even more method chain tests --- tests/source/issue-4053-long-chain-full.rs | 13 ++++++ tests/source/issue-4053-long-chain-middle.rs | 13 ++++++ tests/source/issue-4053-long-chain-parent.rs | 13 ++++++ tests/source/issue-4053-short-chain-full.rs | 6 +++ tests/source/issue-4053-short-chain-middle.rs | 7 ++++ tests/source/issue-4053-short-chain-parent.rs | 6 +++ tests/source/issue-4053.rs | 39 ------------------ tests/target/issue-4053-long-chain-full.rs | 16 ++++++++ tests/target/issue-4053-long-chain-middle.rs | 13 ++++++ tests/target/issue-4053-long-chain-parent.rs | 15 +++++++ tests/target/issue-4053-short-chain-full.rs | 5 +++ tests/target/issue-4053-short-chain-middle.rs | 7 ++++ tests/target/issue-4053-short-chain-parent.rs | 7 ++++ tests/target/issue-4053.rs | 41 ------------------- 14 files changed, 121 insertions(+), 80 deletions(-) create mode 100644 tests/source/issue-4053-long-chain-full.rs create mode 100644 tests/source/issue-4053-long-chain-middle.rs create mode 100644 tests/source/issue-4053-long-chain-parent.rs create mode 100644 tests/source/issue-4053-short-chain-full.rs create mode 100644 tests/source/issue-4053-short-chain-middle.rs create mode 100644 tests/source/issue-4053-short-chain-parent.rs delete mode 100644 tests/source/issue-4053.rs create mode 100644 tests/target/issue-4053-long-chain-full.rs create mode 100644 tests/target/issue-4053-long-chain-middle.rs create mode 100644 tests/target/issue-4053-long-chain-parent.rs create mode 100644 tests/target/issue-4053-short-chain-full.rs create mode 100644 tests/target/issue-4053-short-chain-middle.rs create mode 100644 tests/target/issue-4053-short-chain-parent.rs delete mode 100644 tests/target/issue-4053.rs diff --git a/tests/source/issue-4053-long-chain-full.rs b/tests/source/issue-4053-long-chain-full.rs new file mode 100644 index 00000000000..e9c62e1d75b --- /dev/null +++ b/tests/source/issue-4053-long-chain-full.rs @@ -0,0 +1,13 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-full.rs","range":[4,12]}] + +fn method_chain(val: Option) { + let _ = val.map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); +} diff --git a/tests/source/issue-4053-long-chain-middle.rs b/tests/source/issue-4053-long-chain-middle.rs new file mode 100644 index 00000000000..c32a311e7d7 --- /dev/null +++ b/tests/source/issue-4053-long-chain-middle.rs @@ -0,0 +1,13 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-middle.rs","range":[9,9]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); +} diff --git a/tests/source/issue-4053-long-chain-parent.rs b/tests/source/issue-4053-long-chain-parent.rs new file mode 100644 index 00000000000..6b23aae8843 --- /dev/null +++ b/tests/source/issue-4053-long-chain-parent.rs @@ -0,0 +1,13 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-parent.rs","range":[4,4]}] + +fn method_chain(val: Option) { + let _ = val.map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); +} diff --git a/tests/source/issue-4053-short-chain-full.rs b/tests/source/issue-4053-short-chain-full.rs new file mode 100644 index 00000000000..9d11af3e5bb --- /dev/null +++ b/tests/source/issue-4053-short-chain-full.rs @@ -0,0 +1,6 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-full.rs","range":[4,5]}] + +fn method_chain(val: Option) { + let _ = val.map(|val| val) + .unwrap(); +} diff --git a/tests/source/issue-4053-short-chain-middle.rs b/tests/source/issue-4053-short-chain-middle.rs new file mode 100644 index 00000000000..8bbadd0c70d --- /dev/null +++ b/tests/source/issue-4053-short-chain-middle.rs @@ -0,0 +1,7 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-middle.rs","range":[5,5]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .unwrap(); +} diff --git a/tests/source/issue-4053-short-chain-parent.rs b/tests/source/issue-4053-short-chain-parent.rs new file mode 100644 index 00000000000..68f7a4db4cd --- /dev/null +++ b/tests/source/issue-4053-short-chain-parent.rs @@ -0,0 +1,6 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-parent.rs","range":[4,4]}] + +fn method_chain(val: Option) { + let _ = val.map(|val| val) + .unwrap(); +} diff --git a/tests/source/issue-4053.rs b/tests/source/issue-4053.rs deleted file mode 100644 index 118106bbcce..00000000000 --- a/tests/source/issue-4053.rs +++ /dev/null @@ -1,39 +0,0 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[8,8]},{"file":"tests/source/issue-4053.rs","range":[17,17]},{"file":"tests/source/issue-4053.rs","range":[23,23]},{"file":"tests/source/issue-4053.rs","range":[36,36]}] - -fn method_chain(val: Option) { - // Format one line of a short expression. If we were formatting the whole - // expression we would put it all on one line, so we need to handle it - // differently if we're formatting just one part of the expression. - let _ = val - .map(|val| val) - .unwrap(); - - // Format one method call in a large method chain. - let _ = val - .map(|val| val) - .map(|val| val).map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .unwrap(); - - // Format the first part of a large method chain. - let _ = val.map(|val| val).map(|val| val) - .map(|val| val) - .map(|val| val).map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .unwrap(); -} - -fn match_expr(x: i32) { - match x { - 0 => {}, - _ => {}, - }; -} diff --git a/tests/target/issue-4053-long-chain-full.rs b/tests/target/issue-4053-long-chain-full.rs new file mode 100644 index 00000000000..6c55987e0f0 --- /dev/null +++ b/tests/target/issue-4053-long-chain-full.rs @@ -0,0 +1,16 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-full.rs","range":[4,12]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053-long-chain-middle.rs b/tests/target/issue-4053-long-chain-middle.rs new file mode 100644 index 00000000000..752d468ef8d --- /dev/null +++ b/tests/target/issue-4053-long-chain-middle.rs @@ -0,0 +1,13 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-middle.rs","range":[9,9]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053-long-chain-parent.rs b/tests/target/issue-4053-long-chain-parent.rs new file mode 100644 index 00000000000..e7aff44ffda --- /dev/null +++ b/tests/target/issue-4053-long-chain-parent.rs @@ -0,0 +1,15 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-parent.rs","range":[4,4]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053-short-chain-full.rs b/tests/target/issue-4053-short-chain-full.rs new file mode 100644 index 00000000000..0a4c376471b --- /dev/null +++ b/tests/target/issue-4053-short-chain-full.rs @@ -0,0 +1,5 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-full.rs","range":[4,5]}] + +fn method_chain(val: Option) { + let _ = val.map(|val| val).unwrap(); +} diff --git a/tests/target/issue-4053-short-chain-middle.rs b/tests/target/issue-4053-short-chain-middle.rs new file mode 100644 index 00000000000..1d7fe791b54 --- /dev/null +++ b/tests/target/issue-4053-short-chain-middle.rs @@ -0,0 +1,7 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-middle.rs","range":[5,5]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053-short-chain-parent.rs b/tests/target/issue-4053-short-chain-parent.rs new file mode 100644 index 00000000000..0770e940813 --- /dev/null +++ b/tests/target/issue-4053-short-chain-parent.rs @@ -0,0 +1,7 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-parent.rs","range":[4,4]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053.rs b/tests/target/issue-4053.rs deleted file mode 100644 index 8b2cb5209e2..00000000000 --- a/tests/target/issue-4053.rs +++ /dev/null @@ -1,41 +0,0 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053.rs","range":[8,8]},{"file":"tests/source/issue-4053.rs","range":[17,17]},{"file":"tests/source/issue-4053.rs","range":[23,23]},{"file":"tests/source/issue-4053.rs","range":[36,36]}] - -fn method_chain(val: Option) { - // Format one line of a short expression. If we were formatting the whole - // expression we would put it all on one line, so we need to handle it - // differently if we're formatting just one part of the expression. - let _ = val - .map(|val| val) - .unwrap(); - - // Format one method call in a large method chain. - let _ = val - .map(|val| val) - .map(|val| val).map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .unwrap(); - - // Format the first part of a large method chain. - let _ = val - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val).map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .map(|val| val) - .unwrap(); -} - -fn match_expr(x: i32) { - match x { - 0 => {}, - _ => {}, - }; -} From 007931ab1253181031e614413d3b475ae9084908 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 31 Mar 2026 16:38:29 -0700 Subject: [PATCH 05/17] Determine if we can format to a single line Check the span of the chain against the selected lines to format. Only allow formatting the chain as a single line if the entire chain is covered by the selected range. --- src/chains.rs | 82 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index 90adb67ad43..b9c30f2a8d6 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -71,7 +71,7 @@ use crate::rewrite::{ ExceedsMaxWidthError, Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult, }; use crate::shape::Shape; -use crate::source_map::SpanUtils; +use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::utils::{ self, filtered_str_fits, first_line_width, last_line_extendable, last_line_width, mk_sp, rewrite_ident, trimmed_last_line_width, wrap_str, @@ -104,13 +104,25 @@ fn format_chain_item( // only when item.rewrite_result() returns RewriteError::ExceedsMaxWidth. // It may be inappropriate to call format_overflow_style on other RewriteError // since the current approach retries formatting if allow_overflow is true - item.rewrite_result(context, rewrite_shape) + rewrite_chain_item(item, context, rewrite_shape) .or_else(|_| format_overflow_style(item.span, context).unknown_error()) } else { - item.rewrite_result(context, rewrite_shape) + rewrite_chain_item(item, context, rewrite_shape) } } +fn rewrite_chain_item( + item: &ChainItem, + context: &RewriteContext<'_>, + rewrite_shape: Shape, +) -> RewriteResult { + item.rewrite_result(context, rewrite_shape) + .or_else(|err| match err { + RewriteError::SkipFormatting => Ok(context.snippet(item.span).to_owned()), + _ => Err(err), + }) +} + fn get_block_child_shape( prev_ends_with_block: bool, context: &RewriteContext<'_>, @@ -555,13 +567,21 @@ impl Rewrite for Chain { fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { debug!("rewrite chain {:?} {:?}", self, shape); + let first = self.children.first().unwrap_or(&self.parent); + let last = self.children.last().unwrap_or(&self.parent); + let children_span = mk_sp(first.span.lo(), last.span.hi()); + let full_span = self.parent.span.with_hi(children_span.hi()); + let allow_single_line = context.config.file_lines().is_all() + || context + .config + .file_lines() + .contains(&context.psess.lookup_line_range(full_span)); + let mut formatter = match context.config.indent_style() { - IndentStyle::Block => { - Box::new(ChainFormatterBlock::new(self)) as Box - } - IndentStyle::Visual => { - Box::new(ChainFormatterVisual::new(self)) as Box - } + IndentStyle::Block => Box::new(ChainFormatterBlock::new(self, allow_single_line)) + as Box, + IndentStyle::Visual => Box::new(ChainFormatterVisual::new(self, allow_single_line)) + as Box, }; formatter.format_root(&self.parent, context, shape)?; @@ -570,11 +590,6 @@ impl Rewrite for Chain { .max_width_error(shape.width, self.parent.span); } - let first = self.children.first().unwrap_or(&self.parent); - let last = self.children.last().unwrap_or(&self.parent); - let children_span = mk_sp(first.span.lo(), last.span.hi()); - let full_span = self.parent.span.with_hi(children_span.hi()); - // Decide how to layout the rest of the chain. let child_shape = formatter.child_shape(context, shape, children_span)?; @@ -642,10 +657,12 @@ struct ChainFormatterShared<'a> { child_count: usize, // Whether elements are allowed to overflow past the max_width limit allow_overflow: bool, + // Whether the chain is allowed to collapse back onto a single line. + allow_single_line: bool, } impl<'a> ChainFormatterShared<'a> { - fn new(chain: &'a Chain) -> ChainFormatterShared<'a> { + fn new(chain: &'a Chain, allow_single_line: bool) -> ChainFormatterShared<'a> { ChainFormatterShared { children: &chain.children, rewrites: Vec::with_capacity(chain.children.len() + 1), @@ -653,6 +670,7 @@ impl<'a> ChainFormatterShared<'a> { child_count: chain.children.len(), // TODO(calebcartwright) allow_overflow: false, + allow_single_line, } } @@ -736,19 +754,20 @@ impl<'a> ChainFormatterShared<'a> { } .saturating_sub(almost_total); - let all_in_one_line = !self.children.iter().any(ChainItem::is_comment) + let all_in_one_line = self.allow_single_line + && !self.children.iter().any(ChainItem::is_comment) && self.rewrites.iter().all(|s| !s.contains('\n')) && one_line_budget > 0; let last_shape = if all_in_one_line { shape.sub_width(last.tries, last.span)? - } else if extendable { + } else if extendable && self.allow_single_line { child_shape.sub_width(last.tries, last.span)? } else { child_shape.sub_width(shape.rhs_overhead(context.config) + last.tries, last.span)? }; let mut last_subexpr_str = None; - if all_in_one_line || extendable { + if all_in_one_line || (extendable && self.allow_single_line) { // First we try to 'overflow' the last child and see if it looks better than using // vertical layout. let one_line_shape = if context.use_block_indent() { @@ -851,9 +870,9 @@ struct ChainFormatterBlock<'a> { } impl<'a> ChainFormatterBlock<'a> { - fn new(chain: &'a Chain) -> ChainFormatterBlock<'a> { + fn new(chain: &'a Chain, allow_single_line: bool) -> ChainFormatterBlock<'a> { ChainFormatterBlock { - shared: ChainFormatterShared::new(chain), + shared: ChainFormatterShared::new(chain, allow_single_line), root_ends_with_block: false, } } @@ -866,18 +885,21 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> { context: &RewriteContext<'_>, shape: Shape, ) -> Result<(), RewriteError> { - let mut root_rewrite: String = parent.rewrite_result(context, shape)?; + let mut root_rewrite: String = rewrite_chain_item(parent, context, shape)?; let mut root_ends_with_block = parent.kind.is_block_like(context, &root_rewrite); let tab_width = context.config.tab_spaces().saturating_sub(shape.offset); - while root_rewrite.len() <= tab_width && !root_rewrite.contains('\n') { + while self.shared.allow_single_line + && root_rewrite.len() <= tab_width + && !root_rewrite.contains('\n') + { let item = &self.shared.children[0]; if let ChainItemKind::Comment(..) = item.kind { break; } let shape = shape.offset_left(root_rewrite.len(), item.span)?; - match &item.rewrite_result(context, shape) { + match &rewrite_chain_item(item, context, shape) { Ok(rewrite) => root_rewrite.push_str(rewrite), Err(_) => break, } @@ -939,9 +961,9 @@ struct ChainFormatterVisual<'a> { } impl<'a> ChainFormatterVisual<'a> { - fn new(chain: &'a Chain) -> ChainFormatterVisual<'a> { + fn new(chain: &'a Chain, allow_single_line: bool) -> ChainFormatterVisual<'a> { ChainFormatterVisual { - shared: ChainFormatterShared::new(chain), + shared: ChainFormatterShared::new(chain, allow_single_line), offset: 0, } } @@ -955,7 +977,7 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { shape: Shape, ) -> Result<(), RewriteError> { let parent_shape = shape.visual_indent(0); - let mut root_rewrite = parent.rewrite_result(context, parent_shape)?; + let mut root_rewrite = rewrite_chain_item(parent, context, parent_shape)?; let multiline = root_rewrite.contains('\n'); self.offset = if multiline { last_line_width(&root_rewrite).saturating_sub(shape.used_width()) @@ -963,7 +985,9 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { trimmed_last_line_width(&root_rewrite) }; - if !multiline || parent.kind.is_block_like(context, &root_rewrite) { + if self.shared.allow_single_line + && (!multiline || parent.kind.is_block_like(context, &root_rewrite)) + { let item = &self.shared.children[0]; if let ChainItemKind::Comment(..) = item.kind { self.shared.rewrites.push(root_rewrite); @@ -972,13 +996,13 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { let child_shape = parent_shape .visual_indent(self.offset) .sub_width(self.offset, item.span)?; - let rewrite = item.rewrite_result(context, child_shape)?; + let rewrite = rewrite_chain_item(item, context, child_shape)?; if filtered_str_fits(&rewrite, context.config.max_width(), shape) { root_rewrite.push_str(&rewrite); } else { // We couldn't fit in at the visual indent, try the last // indent. - let rewrite = item.rewrite_result(context, parent_shape)?; + let rewrite = rewrite_chain_item(item, context, parent_shape)?; root_rewrite.push_str(&rewrite); self.offset = 0; } From 6f4797182e02b7f7dd395b29e374c79df4344d33 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 31 Mar 2026 17:00:20 -0700 Subject: [PATCH 06/17] Allow formatting part of a method chain --- src/chains.rs | 99 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 20 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index b9c30f2a8d6..93e7c39d925 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -116,6 +116,15 @@ fn rewrite_chain_item( context: &RewriteContext<'_>, rewrite_shape: Shape, ) -> RewriteResult { + if !context.config.file_lines().is_all() + && !context + .config + .file_lines() + .intersects(&context.psess.lookup_line_range(item.span)) + { + return Ok(context.snippet(item.span).to_owned()); + } + item.rewrite_result(context, rewrite_shape) .or_else(|err| match err { RewriteError::SkipFormatting => Ok(context.snippet(item.span).to_owned()), @@ -571,6 +580,11 @@ impl Rewrite for Chain { let last = self.children.last().unwrap_or(&self.parent); let children_span = mk_sp(first.span.lo(), last.span.hi()); let full_span = self.parent.span.with_hi(children_span.hi()); + let partial_chain = !context.config.file_lines().is_all() + && !context + .config + .file_lines() + .contains(&context.psess.lookup_line_range(full_span)); let allow_single_line = context.config.file_lines().is_all() || context .config @@ -578,26 +592,36 @@ impl Rewrite for Chain { .contains(&context.psess.lookup_line_range(full_span)); let mut formatter = match context.config.indent_style() { - IndentStyle::Block => Box::new(ChainFormatterBlock::new(self, allow_single_line)) - as Box, - IndentStyle::Visual => Box::new(ChainFormatterVisual::new(self, allow_single_line)) - as Box, + IndentStyle::Block => Box::new(ChainFormatterBlock::new( + self, + allow_single_line, + partial_chain, + )) as Box, + IndentStyle::Visual => Box::new(ChainFormatterVisual::new( + self, + allow_single_line, + partial_chain, + )) as Box, }; - formatter.format_root(&self.parent, context, shape)?; - if let Some(result) = formatter.pure_root() { - return wrap_str(result, context.config.max_width(), shape) - .max_width_error(shape.width, self.parent.span); - } + let rewrite = (|| { + formatter.format_root(&self.parent, context, shape)?; + if let Some(result) = formatter.pure_root() { + return wrap_str(result, context.config.max_width(), shape) + .max_width_error(shape.width, self.parent.span); + } - // Decide how to layout the rest of the chain. - let child_shape = formatter.child_shape(context, shape, children_span)?; + // Decide how to layout the rest of the chain. + let child_shape = formatter.child_shape(context, shape, children_span)?; - formatter.format_children(context, child_shape)?; - formatter.format_last_child(context, shape, child_shape)?; + formatter.format_children(context, child_shape)?; + formatter.format_last_child(context, shape, child_shape)?; - let result = formatter.join_rewrites(context, child_shape)?; - wrap_str(result, context.config.max_width(), shape).max_width_error(shape.width, full_span) + let result = formatter.join_rewrites(context, child_shape)?; + wrap_str(result, context.config.max_width(), shape) + .max_width_error(shape.width, full_span) + })(); + rewrite } } @@ -659,10 +683,19 @@ struct ChainFormatterShared<'a> { allow_overflow: bool, // Whether the chain is allowed to collapse back onto a single line. allow_single_line: bool, + // Whether we are formatting only part of the chain and should preserve + // the original grouping of unselected items. + partial_chain: bool, + // End position of the current root rewrite in the original source. + root_span_end: BytePos, } impl<'a> ChainFormatterShared<'a> { - fn new(chain: &'a Chain, allow_single_line: bool) -> ChainFormatterShared<'a> { + fn new( + chain: &'a Chain, + allow_single_line: bool, + partial_chain: bool, + ) -> ChainFormatterShared<'a> { ChainFormatterShared { children: &chain.children, rewrites: Vec::with_capacity(chain.children.len() + 1), @@ -671,6 +704,8 @@ impl<'a> ChainFormatterShared<'a> { // TODO(calebcartwright) allow_overflow: false, allow_single_line, + partial_chain, + root_span_end: chain.parent.span.hi(), } } @@ -849,14 +884,28 @@ impl<'a> ChainFormatterShared<'a> { let mut result = rewrite_iter.next().unwrap().clone(); let children_iter = self.children.iter(); let iter = rewrite_iter.zip(children_iter); + let mut prev_span_end = Some(self.root_span_end); for (rewrite, chain_item) in iter { match chain_item.kind { ChainItemKind::Comment(_, CommentPosition::Back) => result.push(' '), ChainItemKind::Comment(_, CommentPosition::Top) => result.push_str(&connector), + _ if self.partial_chain && !self.fits_single_line => { + let current_range = context.psess.lookup_line_range(chain_item.span); + let item_is_selected = context.config.file_lines().intersects(¤t_range); + let original_gap = prev_span_end + .map(|prev_end| context.snippet(mk_sp(prev_end, chain_item.span.lo()))) + .unwrap_or("\n"); + if item_is_selected { + result.push_str(&connector); + } else if original_gap.contains('\n') { + result.push_str(original_gap); + } + } _ => result.push_str(&connector), } result.push_str(rewrite); + prev_span_end = Some(chain_item.span.hi()); } Ok(result) @@ -870,9 +919,13 @@ struct ChainFormatterBlock<'a> { } impl<'a> ChainFormatterBlock<'a> { - fn new(chain: &'a Chain, allow_single_line: bool) -> ChainFormatterBlock<'a> { + fn new( + chain: &'a Chain, + allow_single_line: bool, + partial_chain: bool, + ) -> ChainFormatterBlock<'a> { ChainFormatterBlock { - shared: ChainFormatterShared::new(chain, allow_single_line), + shared: ChainFormatterShared::new(chain, allow_single_line, partial_chain), root_ends_with_block: false, } } @@ -906,6 +959,7 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> { root_ends_with_block = last_line_extendable(&root_rewrite); + self.shared.root_span_end = item.span.hi(); self.shared.children = &self.shared.children[1..]; if self.shared.children.is_empty() { break; @@ -961,9 +1015,13 @@ struct ChainFormatterVisual<'a> { } impl<'a> ChainFormatterVisual<'a> { - fn new(chain: &'a Chain, allow_single_line: bool) -> ChainFormatterVisual<'a> { + fn new( + chain: &'a Chain, + allow_single_line: bool, + partial_chain: bool, + ) -> ChainFormatterVisual<'a> { ChainFormatterVisual { - shared: ChainFormatterShared::new(chain, allow_single_line), + shared: ChainFormatterShared::new(chain, allow_single_line, partial_chain), offset: 0, } } @@ -1007,6 +1065,7 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { self.offset = 0; } + self.shared.root_span_end = item.span.hi(); self.shared.children = &self.shared.children[1..]; } From 820b67be70fd61b5a4d0824b71247ce026f4987b Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Wed, 1 Apr 2026 13:00:29 -0700 Subject: [PATCH 07/17] Simplify rewrite_result a bit --- src/chains.rs | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index 93e7c39d925..6b567ca20b2 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -580,16 +580,11 @@ impl Rewrite for Chain { let last = self.children.last().unwrap_or(&self.parent); let children_span = mk_sp(first.span.lo(), last.span.hi()); let full_span = self.parent.span.with_hi(children_span.hi()); - let partial_chain = !context.config.file_lines().is_all() - && !context - .config - .file_lines() - .contains(&context.psess.lookup_line_range(full_span)); - let allow_single_line = context.config.file_lines().is_all() - || context - .config - .file_lines() - .contains(&context.psess.lookup_line_range(full_span)); + let partial_chain = !context + .config + .file_lines() + .contains(&context.psess.lookup_line_range(full_span)); + let allow_single_line = !partial_chain; let mut formatter = match context.config.indent_style() { IndentStyle::Block => Box::new(ChainFormatterBlock::new( @@ -604,24 +599,20 @@ impl Rewrite for Chain { )) as Box, }; - let rewrite = (|| { - formatter.format_root(&self.parent, context, shape)?; - if let Some(result) = formatter.pure_root() { - return wrap_str(result, context.config.max_width(), shape) - .max_width_error(shape.width, self.parent.span); - } + formatter.format_root(&self.parent, context, shape)?; + if let Some(result) = formatter.pure_root() { + return wrap_str(result, context.config.max_width(), shape) + .max_width_error(shape.width, self.parent.span); + } - // Decide how to layout the rest of the chain. - let child_shape = formatter.child_shape(context, shape, children_span)?; + // Decide how to layout the rest of the chain. + let child_shape = formatter.child_shape(context, shape, children_span)?; - formatter.format_children(context, child_shape)?; - formatter.format_last_child(context, shape, child_shape)?; + formatter.format_children(context, child_shape)?; + formatter.format_last_child(context, shape, child_shape)?; - let result = formatter.join_rewrites(context, child_shape)?; - wrap_str(result, context.config.max_width(), shape) - .max_width_error(shape.width, full_span) - })(); - rewrite + let result = formatter.join_rewrites(context, child_shape)?; + wrap_str(result, context.config.max_width(), shape).max_width_error(shape.width, full_span) } } From 2af341722940bc246381782e89167877743bb4d7 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Wed, 1 Apr 2026 14:47:30 -0700 Subject: [PATCH 08/17] Add test for partially selecting a chain item --- tests/source/issue-4053-partial-item.rs | 19 +++++++++++++++++++ tests/target/issue-4053-partial-item.rs | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/source/issue-4053-partial-item.rs create mode 100644 tests/target/issue-4053-partial-item.rs diff --git a/tests/source/issue-4053-partial-item.rs b/tests/source/issue-4053-partial-item.rs new file mode 100644 index 00000000000..be3814f1985 --- /dev/null +++ b/tests/source/issue-4053-partial-item.rs @@ -0,0 +1,19 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-partial-item.rs","range":[7,7]},{"file":"tests/source/issue-4053-partial-item.rs","range":[12,13]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| { + println!("..."); + val + }) + .map(|val| val) + .map(|val| { + println!("..."); + val + }) + .map(|val| val) + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053-partial-item.rs b/tests/target/issue-4053-partial-item.rs new file mode 100644 index 00000000000..3a920e0fea9 --- /dev/null +++ b/tests/target/issue-4053-partial-item.rs @@ -0,0 +1,19 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-partial-item.rs","range":[7,7]},{"file":"tests/source/issue-4053-partial-item.rs","range":[12,13]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .map(|val| val).map(|val| val) + .map(|val| { + println!("..."); + val + }) + .map(|val| val) + .map(|val| { + println!("..."); + val + }) + .map(|val| val) + .map(|val| val) + .unwrap(); +} From f7b2c65ccf856b2d6c57293687603a5323e6171c Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Wed, 1 Apr 2026 14:48:49 -0700 Subject: [PATCH 09/17] Cleanup rewrite_chain_item --- src/chains.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index 6b567ca20b2..835907f41bd 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -111,25 +111,24 @@ fn format_chain_item( } } +/// Attempts to rewrite the chain item if it is covered by the selected file lines. fn rewrite_chain_item( item: &ChainItem, context: &RewriteContext<'_>, rewrite_shape: Shape, ) -> RewriteResult { - if !context.config.file_lines().is_all() - && !context - .config - .file_lines() - .intersects(&context.psess.lookup_line_range(item.span)) + // Don't attempt to format the item if its outside the selected range of lines, + // since doing so will cause `rewrite_result` to produce an error that will then + // cause us to bail out of rewriting the chain as a whole. + if !context + .config + .file_lines() + .intersects(&context.psess.lookup_line_range(item.span)) { return Ok(context.snippet(item.span).to_owned()); } item.rewrite_result(context, rewrite_shape) - .or_else(|err| match err { - RewriteError::SkipFormatting => Ok(context.snippet(item.span).to_owned()), - _ => Err(err), - }) } fn get_block_child_shape( From 95406e8ad16757d3684e37287b9c6b0d2a8c9d78 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Wed, 1 Apr 2026 16:38:56 -0700 Subject: [PATCH 10/17] A lil bit of cleanup in join_rewrites --- src/chains.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index 835907f41bd..7cdc84e7e65 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -874,28 +874,30 @@ impl<'a> ChainFormatterShared<'a> { let mut result = rewrite_iter.next().unwrap().clone(); let children_iter = self.children.iter(); let iter = rewrite_iter.zip(children_iter); - let mut prev_span_end = Some(self.root_span_end); + let mut prev_span_end = self.root_span_end; for (rewrite, chain_item) in iter { match chain_item.kind { ChainItemKind::Comment(_, CommentPosition::Back) => result.push(' '), ChainItemKind::Comment(_, CommentPosition::Top) => result.push_str(&connector), - _ if self.partial_chain && !self.fits_single_line => { + + // If we're only formatting part of the chain, we need to preserve the layout of + // any items not covered by the selected lines. + _ if self.partial_chain => { let current_range = context.psess.lookup_line_range(chain_item.span); let item_is_selected = context.config.file_lines().intersects(¤t_range); - let original_gap = prev_span_end - .map(|prev_end| context.snippet(mk_sp(prev_end, chain_item.span.lo()))) - .unwrap_or("\n"); + let original_gap = context.snippet(mk_sp(prev_span_end, chain_item.span.lo())); if item_is_selected { result.push_str(&connector); } else if original_gap.contains('\n') { result.push_str(original_gap); } } + _ => result.push_str(&connector), } result.push_str(rewrite); - prev_span_end = Some(chain_item.span.hi()); + prev_span_end = chain_item.span.hi(); } Ok(result) From 145f7471addeac70077cc4e168a3db87a25f94b3 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 14 Apr 2026 12:06:46 -0700 Subject: [PATCH 11/17] Fix handling of whitespace around comments --- src/chains.rs | 10 +++++++--- tests/source/issue-4053-comments.rs | 16 ++++++++++++++++ tests/target/issue-4053-comments.rs | 16 ++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 tests/source/issue-4053-comments.rs create mode 100644 tests/target/issue-4053-comments.rs diff --git a/src/chains.rs b/src/chains.rs index 7cdc84e7e65..e428885c6f8 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -877,16 +877,20 @@ impl<'a> ChainFormatterShared<'a> { let mut prev_span_end = self.root_span_end; for (rewrite, chain_item) in iter { + let original_gap = context.snippet(mk_sp(prev_span_end, chain_item.span.lo())); + let item_is_selected = context + .config + .file_lines() + .intersects(&context.psess.lookup_line_range(chain_item.span)); + match chain_item.kind { + ChainItemKind::Comment(..) if self.partial_chain && !item_is_selected => {} ChainItemKind::Comment(_, CommentPosition::Back) => result.push(' '), ChainItemKind::Comment(_, CommentPosition::Top) => result.push_str(&connector), // If we're only formatting part of the chain, we need to preserve the layout of // any items not covered by the selected lines. _ if self.partial_chain => { - let current_range = context.psess.lookup_line_range(chain_item.span); - let item_is_selected = context.config.file_lines().intersects(¤t_range); - let original_gap = context.snippet(mk_sp(prev_span_end, chain_item.span.lo())); if item_is_selected { result.push_str(&connector); } else if original_gap.contains('\n') { diff --git a/tests/source/issue-4053-comments.rs b/tests/source/issue-4053-comments.rs new file mode 100644 index 00000000000..2e31ca5fb5e --- /dev/null +++ b/tests/source/issue-4053-comments.rs @@ -0,0 +1,16 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-comments.rs","range":[10,10]}] + +fn method_chain(val: Option) { + let _ = val.map(|val| val).map(|val| val) + .map(|val| val) + // top comment + .map(|val| val).map(|val| val) + .map(|val| val) // back comment + .map(|val| val) // back comment + .map(|val| val) + .map(|val| val) + .map(|val| val) + // top comment + + .unwrap(); +} diff --git a/tests/target/issue-4053-comments.rs b/tests/target/issue-4053-comments.rs new file mode 100644 index 00000000000..135d4464a40 --- /dev/null +++ b/tests/target/issue-4053-comments.rs @@ -0,0 +1,16 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-comments.rs","range":[10,10]}] + +fn method_chain(val: Option) { + let _ = val.map(|val| val).map(|val| val) + .map(|val| val) + // top comment + .map(|val| val).map(|val| val) + .map(|val| val) // back comment + .map(|val| val) // back comment + .map(|val| val) + .map(|val| val) + .map(|val| val) + // top comment + + .unwrap(); +} From b0bef60e221e513655d333dbf2b0db7074162162 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 14 Apr 2026 12:09:52 -0700 Subject: [PATCH 12/17] Fix handling of inline gaps --- src/chains.rs | 2 +- tests/source/issue-4053-inline-gap.rs | 9 +++++++++ tests/target/issue-4053-inline-gap.rs | 9 +++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-4053-inline-gap.rs create mode 100644 tests/target/issue-4053-inline-gap.rs diff --git a/src/chains.rs b/src/chains.rs index e428885c6f8..572088aba70 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -893,7 +893,7 @@ impl<'a> ChainFormatterShared<'a> { _ if self.partial_chain => { if item_is_selected { result.push_str(&connector); - } else if original_gap.contains('\n') { + } else { result.push_str(original_gap); } } diff --git a/tests/source/issue-4053-inline-gap.rs b/tests/source/issue-4053-inline-gap.rs new file mode 100644 index 00000000000..bc35be034a8 --- /dev/null +++ b/tests/source/issue-4053-inline-gap.rs @@ -0,0 +1,9 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-inline-gap.rs","range":[7,7]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .map(|val| val) .map(|val| val) + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053-inline-gap.rs b/tests/target/issue-4053-inline-gap.rs new file mode 100644 index 00000000000..5627fd5e21a --- /dev/null +++ b/tests/target/issue-4053-inline-gap.rs @@ -0,0 +1,9 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-inline-gap.rs","range":[7,7]}] + +fn method_chain(val: Option) { + let _ = val + .map(|val| val) + .map(|val| val) .map(|val| val) + .map(|val| val) + .unwrap(); +} From 37dc190eb1ed06c24dba5a6d02a67adac18a9bef Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 14 Apr 2026 12:33:06 -0700 Subject: [PATCH 13/17] Remove redundant parameter --- src/chains.rs | 58 +++++++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index 572088aba70..2949ec8d193 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -579,24 +579,19 @@ impl Rewrite for Chain { let last = self.children.last().unwrap_or(&self.parent); let children_span = mk_sp(first.span.lo(), last.span.hi()); let full_span = self.parent.span.with_hi(children_span.hi()); + let partial_chain = !context .config .file_lines() .contains(&context.psess.lookup_line_range(full_span)); - let allow_single_line = !partial_chain; - - let mut formatter = match context.config.indent_style() { - IndentStyle::Block => Box::new(ChainFormatterBlock::new( - self, - allow_single_line, - partial_chain, - )) as Box, - IndentStyle::Visual => Box::new(ChainFormatterVisual::new( - self, - allow_single_line, - partial_chain, - )) as Box, - }; + + let mut formatter = + match context.config.indent_style() { + IndentStyle::Block => Box::new(ChainFormatterBlock::new(self, partial_chain)) + as Box, + IndentStyle::Visual => Box::new(ChainFormatterVisual::new(self, partial_chain)) + as Box, + }; formatter.format_root(&self.parent, context, shape)?; if let Some(result) = formatter.pure_root() { @@ -671,8 +666,6 @@ struct ChainFormatterShared<'a> { child_count: usize, // Whether elements are allowed to overflow past the max_width limit allow_overflow: bool, - // Whether the chain is allowed to collapse back onto a single line. - allow_single_line: bool, // Whether we are formatting only part of the chain and should preserve // the original grouping of unselected items. partial_chain: bool, @@ -681,11 +674,7 @@ struct ChainFormatterShared<'a> { } impl<'a> ChainFormatterShared<'a> { - fn new( - chain: &'a Chain, - allow_single_line: bool, - partial_chain: bool, - ) -> ChainFormatterShared<'a> { + fn new(chain: &'a Chain, partial_chain: bool) -> ChainFormatterShared<'a> { ChainFormatterShared { children: &chain.children, rewrites: Vec::with_capacity(chain.children.len() + 1), @@ -693,7 +682,6 @@ impl<'a> ChainFormatterShared<'a> { child_count: chain.children.len(), // TODO(calebcartwright) allow_overflow: false, - allow_single_line, partial_chain, root_span_end: chain.parent.span.hi(), } @@ -779,20 +767,20 @@ impl<'a> ChainFormatterShared<'a> { } .saturating_sub(almost_total); - let all_in_one_line = self.allow_single_line + let all_in_one_line = !self.partial_chain && !self.children.iter().any(ChainItem::is_comment) && self.rewrites.iter().all(|s| !s.contains('\n')) && one_line_budget > 0; let last_shape = if all_in_one_line { shape.sub_width(last.tries, last.span)? - } else if extendable && self.allow_single_line { + } else if extendable && !self.partial_chain { child_shape.sub_width(last.tries, last.span)? } else { child_shape.sub_width(shape.rhs_overhead(context.config) + last.tries, last.span)? }; let mut last_subexpr_str = None; - if all_in_one_line || (extendable && self.allow_single_line) { + if all_in_one_line || (extendable && !self.partial_chain) { // First we try to 'overflow' the last child and see if it looks better than using // vertical layout. let one_line_shape = if context.use_block_indent() { @@ -915,13 +903,9 @@ struct ChainFormatterBlock<'a> { } impl<'a> ChainFormatterBlock<'a> { - fn new( - chain: &'a Chain, - allow_single_line: bool, - partial_chain: bool, - ) -> ChainFormatterBlock<'a> { + fn new(chain: &'a Chain, partial_chain: bool) -> ChainFormatterBlock<'a> { ChainFormatterBlock { - shared: ChainFormatterShared::new(chain, allow_single_line, partial_chain), + shared: ChainFormatterShared::new(chain, partial_chain), root_ends_with_block: false, } } @@ -939,7 +923,7 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> { let mut root_ends_with_block = parent.kind.is_block_like(context, &root_rewrite); let tab_width = context.config.tab_spaces().saturating_sub(shape.offset); - while self.shared.allow_single_line + while !self.shared.partial_chain && root_rewrite.len() <= tab_width && !root_rewrite.contains('\n') { @@ -1011,13 +995,9 @@ struct ChainFormatterVisual<'a> { } impl<'a> ChainFormatterVisual<'a> { - fn new( - chain: &'a Chain, - allow_single_line: bool, - partial_chain: bool, - ) -> ChainFormatterVisual<'a> { + fn new(chain: &'a Chain, partial_chain: bool) -> ChainFormatterVisual<'a> { ChainFormatterVisual { - shared: ChainFormatterShared::new(chain, allow_single_line, partial_chain), + shared: ChainFormatterShared::new(chain, partial_chain), offset: 0, } } @@ -1039,7 +1019,7 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { trimmed_last_line_width(&root_rewrite) }; - if self.shared.allow_single_line + if !self.shared.partial_chain && (!multiline || parent.kind.is_block_like(context, &root_rewrite)) { let item = &self.shared.children[0]; From b9805b57f7beec87837d07b62fb5f47285316e4e Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 14 Apr 2026 13:57:56 -0700 Subject: [PATCH 14/17] Remove some redundant code --- src/chains.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index 2949ec8d193..6f7ebd372f5 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -872,7 +872,7 @@ impl<'a> ChainFormatterShared<'a> { .intersects(&context.psess.lookup_line_range(chain_item.span)); match chain_item.kind { - ChainItemKind::Comment(..) if self.partial_chain && !item_is_selected => {} + ChainItemKind::Comment(..) if !item_is_selected => {} ChainItemKind::Comment(_, CommentPosition::Back) => result.push(' '), ChainItemKind::Comment(_, CommentPosition::Top) => result.push_str(&connector), @@ -939,7 +939,6 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> { root_ends_with_block = last_line_extendable(&root_rewrite); - self.shared.root_span_end = item.span.hi(); self.shared.children = &self.shared.children[1..]; if self.shared.children.is_empty() { break; @@ -1041,7 +1040,6 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { self.offset = 0; } - self.shared.root_span_end = item.span.hi(); self.shared.children = &self.shared.children[1..]; } From f1cae46df8a600468c151bcd0c50f0f2788aa1b0 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 14 Apr 2026 14:32:54 -0700 Subject: [PATCH 15/17] Add test for root absorbtion when block formatting --- tests/source/issue-4053-root-absorption.rs | 7 +++++++ tests/target/issue-4053-root-absorption.rs | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 tests/source/issue-4053-root-absorption.rs create mode 100644 tests/target/issue-4053-root-absorption.rs diff --git a/tests/source/issue-4053-root-absorption.rs b/tests/source/issue-4053-root-absorption.rs new file mode 100644 index 00000000000..1a1c8385dc8 --- /dev/null +++ b/tests/source/issue-4053-root-absorption.rs @@ -0,0 +1,7 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-root-absorption.rs","range":[4,4]}] + +fn method_chain(val: Option) { + val + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053-root-absorption.rs b/tests/target/issue-4053-root-absorption.rs new file mode 100644 index 00000000000..8d5971f2b9f --- /dev/null +++ b/tests/target/issue-4053-root-absorption.rs @@ -0,0 +1,7 @@ +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-root-absorption.rs","range":[4,4]}] + +fn method_chain(val: Option) { + val + .map(|val| val) + .unwrap(); +} From cbd206eb35bcdbaa6509837d367c4c96356de70c Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 14 Apr 2026 14:46:17 -0700 Subject: [PATCH 16/17] Add same test but for visual formatting --- tests/source/issue-4053-root-absorption-visual.rs | 8 ++++++++ tests/target/issue-4053-root-absorption-visual.rs | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 tests/source/issue-4053-root-absorption-visual.rs create mode 100644 tests/target/issue-4053-root-absorption-visual.rs diff --git a/tests/source/issue-4053-root-absorption-visual.rs b/tests/source/issue-4053-root-absorption-visual.rs new file mode 100644 index 00000000000..154a3349207 --- /dev/null +++ b/tests/source/issue-4053-root-absorption-visual.rs @@ -0,0 +1,8 @@ +// rustfmt-indent_style: Visual +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-root-absorption-visual.rs","range":[5,5]}] + +fn method_chain(val: Option) { + val + .map(|val| val) + .unwrap(); +} diff --git a/tests/target/issue-4053-root-absorption-visual.rs b/tests/target/issue-4053-root-absorption-visual.rs new file mode 100644 index 00000000000..aee9916b374 --- /dev/null +++ b/tests/target/issue-4053-root-absorption-visual.rs @@ -0,0 +1,8 @@ +// rustfmt-indent_style: Visual +// rustfmt-file_lines: [{"file":"tests/source/issue-4053-root-absorption-visual.rs","range":[5,5]}] + +fn method_chain(val: Option) { + val + .map(|val| val) + .unwrap(); +} From a4433a25fe56b2c7e79849ceb55598ef0d4a1b25 Mon Sep 17 00:00:00 2001 From: Nicole LeGare Date: Tue, 14 Apr 2026 15:08:22 -0700 Subject: [PATCH 17/17] Move tests to a common directory --- tests/source/{issue-4053-comments.rs => issue-4053/comments.rs} | 2 +- .../{issue-4053-inline-gap.rs => issue-4053/inline-gap.rs} | 2 +- .../long-chain-full.rs} | 2 +- .../long-chain-middle.rs} | 2 +- .../long-chain-parent.rs} | 2 +- .../{issue-4053-partial-item.rs => issue-4053/partial-item.rs} | 2 +- .../root-absorption-visual.rs} | 2 +- .../root-absorption.rs} | 2 +- .../short-chain-full.rs} | 2 +- .../short-chain-middle.rs} | 2 +- .../short-chain-parent.rs} | 2 +- tests/target/{issue-4053-comments.rs => issue-4053/comments.rs} | 2 +- .../{issue-4053-inline-gap.rs => issue-4053/inline-gap.rs} | 2 +- .../long-chain-full.rs} | 2 +- .../long-chain-middle.rs} | 2 +- .../long-chain-parent.rs} | 2 +- .../{issue-4053-partial-item.rs => issue-4053/partial-item.rs} | 2 +- .../root-absorption-visual.rs} | 2 +- .../root-absorption.rs} | 2 +- .../short-chain-full.rs} | 2 +- .../short-chain-middle.rs} | 2 +- .../short-chain-parent.rs} | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) rename tests/source/{issue-4053-comments.rs => issue-4053/comments.rs} (85%) rename tests/source/{issue-4053-inline-gap.rs => issue-4053/inline-gap.rs} (73%) rename tests/source/{issue-4053-long-chain-full.rs => issue-4053/long-chain-full.rs} (83%) rename tests/source/{issue-4053-long-chain-middle.rs => issue-4053/long-chain-middle.rs} (81%) rename tests/source/{issue-4053-long-chain-parent.rs => issue-4053/long-chain-parent.rs} (83%) rename tests/source/{issue-4053-partial-item.rs => issue-4053/partial-item.rs} (75%) rename tests/source/{issue-4053-root-absorption-visual.rs => issue-4053/root-absorption-visual.rs} (71%) rename tests/source/{issue-4053-root-absorption.rs => issue-4053/root-absorption.rs} (65%) rename tests/source/{issue-4053-short-chain-full.rs => issue-4053/short-chain-full.rs} (65%) rename tests/source/{issue-4053-short-chain-middle.rs => issue-4053/short-chain-middle.rs} (66%) rename tests/source/{issue-4053-short-chain-parent.rs => issue-4053/short-chain-parent.rs} (65%) rename tests/target/{issue-4053-comments.rs => issue-4053/comments.rs} (86%) rename tests/target/{issue-4053-inline-gap.rs => issue-4053/inline-gap.rs} (74%) rename tests/target/{issue-4053-long-chain-full.rs => issue-4053/long-chain-full.rs} (84%) rename tests/target/{issue-4053-long-chain-middle.rs => issue-4053/long-chain-middle.rs} (81%) rename tests/target/{issue-4053-long-chain-parent.rs => issue-4053/long-chain-parent.rs} (83%) rename tests/target/{issue-4053-partial-item.rs => issue-4053/partial-item.rs} (75%) rename tests/target/{issue-4053-root-absorption-visual.rs => issue-4053/root-absorption-visual.rs} (70%) rename tests/target/{issue-4053-root-absorption.rs => issue-4053/root-absorption.rs} (64%) rename tests/target/{issue-4053-short-chain-full.rs => issue-4053/short-chain-full.rs} (63%) rename tests/target/{issue-4053-short-chain-middle.rs => issue-4053/short-chain-middle.rs} (67%) rename tests/target/{issue-4053-short-chain-parent.rs => issue-4053/short-chain-parent.rs} (67%) diff --git a/tests/source/issue-4053-comments.rs b/tests/source/issue-4053/comments.rs similarity index 85% rename from tests/source/issue-4053-comments.rs rename to tests/source/issue-4053/comments.rs index 2e31ca5fb5e..7e5b050786a 100644 --- a/tests/source/issue-4053-comments.rs +++ b/tests/source/issue-4053/comments.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-comments.rs","range":[10,10]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/comments.rs","range":[10,10]}] fn method_chain(val: Option) { let _ = val.map(|val| val).map(|val| val) diff --git a/tests/source/issue-4053-inline-gap.rs b/tests/source/issue-4053/inline-gap.rs similarity index 73% rename from tests/source/issue-4053-inline-gap.rs rename to tests/source/issue-4053/inline-gap.rs index bc35be034a8..137ec239228 100644 --- a/tests/source/issue-4053-inline-gap.rs +++ b/tests/source/issue-4053/inline-gap.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-inline-gap.rs","range":[7,7]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/inline-gap.rs","range":[7,7]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/source/issue-4053-long-chain-full.rs b/tests/source/issue-4053/long-chain-full.rs similarity index 83% rename from tests/source/issue-4053-long-chain-full.rs rename to tests/source/issue-4053/long-chain-full.rs index e9c62e1d75b..ca0960a68bb 100644 --- a/tests/source/issue-4053-long-chain-full.rs +++ b/tests/source/issue-4053/long-chain-full.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-full.rs","range":[4,12]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/long-chain-full.rs","range":[4,12]}] fn method_chain(val: Option) { let _ = val.map(|val| val).map(|val| val) diff --git a/tests/source/issue-4053-long-chain-middle.rs b/tests/source/issue-4053/long-chain-middle.rs similarity index 81% rename from tests/source/issue-4053-long-chain-middle.rs rename to tests/source/issue-4053/long-chain-middle.rs index c32a311e7d7..0e89d4e03df 100644 --- a/tests/source/issue-4053-long-chain-middle.rs +++ b/tests/source/issue-4053/long-chain-middle.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-middle.rs","range":[9,9]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/long-chain-middle.rs","range":[9,9]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/source/issue-4053-long-chain-parent.rs b/tests/source/issue-4053/long-chain-parent.rs similarity index 83% rename from tests/source/issue-4053-long-chain-parent.rs rename to tests/source/issue-4053/long-chain-parent.rs index 6b23aae8843..d2bd3f04bc9 100644 --- a/tests/source/issue-4053-long-chain-parent.rs +++ b/tests/source/issue-4053/long-chain-parent.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-parent.rs","range":[4,4]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/long-chain-parent.rs","range":[4,4]}] fn method_chain(val: Option) { let _ = val.map(|val| val).map(|val| val) diff --git a/tests/source/issue-4053-partial-item.rs b/tests/source/issue-4053/partial-item.rs similarity index 75% rename from tests/source/issue-4053-partial-item.rs rename to tests/source/issue-4053/partial-item.rs index be3814f1985..2f683b57e53 100644 --- a/tests/source/issue-4053-partial-item.rs +++ b/tests/source/issue-4053/partial-item.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-partial-item.rs","range":[7,7]},{"file":"tests/source/issue-4053-partial-item.rs","range":[12,13]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/partial-item.rs","range":[7,7]},{"file":"tests/source/issue-4053/partial-item.rs","range":[12,13]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/source/issue-4053-root-absorption-visual.rs b/tests/source/issue-4053/root-absorption-visual.rs similarity index 71% rename from tests/source/issue-4053-root-absorption-visual.rs rename to tests/source/issue-4053/root-absorption-visual.rs index 154a3349207..5508cdd04bb 100644 --- a/tests/source/issue-4053-root-absorption-visual.rs +++ b/tests/source/issue-4053/root-absorption-visual.rs @@ -1,5 +1,5 @@ // rustfmt-indent_style: Visual -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-root-absorption-visual.rs","range":[5,5]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/root-absorption-visual.rs","range":[5,5]}] fn method_chain(val: Option) { val diff --git a/tests/source/issue-4053-root-absorption.rs b/tests/source/issue-4053/root-absorption.rs similarity index 65% rename from tests/source/issue-4053-root-absorption.rs rename to tests/source/issue-4053/root-absorption.rs index 1a1c8385dc8..f386b1e8ce0 100644 --- a/tests/source/issue-4053-root-absorption.rs +++ b/tests/source/issue-4053/root-absorption.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-root-absorption.rs","range":[4,4]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/root-absorption.rs","range":[4,4]}] fn method_chain(val: Option) { val diff --git a/tests/source/issue-4053-short-chain-full.rs b/tests/source/issue-4053/short-chain-full.rs similarity index 65% rename from tests/source/issue-4053-short-chain-full.rs rename to tests/source/issue-4053/short-chain-full.rs index 9d11af3e5bb..380aa3e8528 100644 --- a/tests/source/issue-4053-short-chain-full.rs +++ b/tests/source/issue-4053/short-chain-full.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-full.rs","range":[4,5]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/short-chain-full.rs","range":[4,5]}] fn method_chain(val: Option) { let _ = val.map(|val| val) diff --git a/tests/source/issue-4053-short-chain-middle.rs b/tests/source/issue-4053/short-chain-middle.rs similarity index 66% rename from tests/source/issue-4053-short-chain-middle.rs rename to tests/source/issue-4053/short-chain-middle.rs index 8bbadd0c70d..9cd17ea503c 100644 --- a/tests/source/issue-4053-short-chain-middle.rs +++ b/tests/source/issue-4053/short-chain-middle.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-middle.rs","range":[5,5]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/short-chain-middle.rs","range":[5,5]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/source/issue-4053-short-chain-parent.rs b/tests/source/issue-4053/short-chain-parent.rs similarity index 65% rename from tests/source/issue-4053-short-chain-parent.rs rename to tests/source/issue-4053/short-chain-parent.rs index 68f7a4db4cd..79c5ecd2b89 100644 --- a/tests/source/issue-4053-short-chain-parent.rs +++ b/tests/source/issue-4053/short-chain-parent.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-parent.rs","range":[4,4]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/short-chain-parent.rs","range":[4,4]}] fn method_chain(val: Option) { let _ = val.map(|val| val) diff --git a/tests/target/issue-4053-comments.rs b/tests/target/issue-4053/comments.rs similarity index 86% rename from tests/target/issue-4053-comments.rs rename to tests/target/issue-4053/comments.rs index 135d4464a40..d3b67177d94 100644 --- a/tests/target/issue-4053-comments.rs +++ b/tests/target/issue-4053/comments.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-comments.rs","range":[10,10]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/comments.rs","range":[10,10]}] fn method_chain(val: Option) { let _ = val.map(|val| val).map(|val| val) diff --git a/tests/target/issue-4053-inline-gap.rs b/tests/target/issue-4053/inline-gap.rs similarity index 74% rename from tests/target/issue-4053-inline-gap.rs rename to tests/target/issue-4053/inline-gap.rs index 5627fd5e21a..d42548fc268 100644 --- a/tests/target/issue-4053-inline-gap.rs +++ b/tests/target/issue-4053/inline-gap.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-inline-gap.rs","range":[7,7]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/inline-gap.rs","range":[7,7]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/target/issue-4053-long-chain-full.rs b/tests/target/issue-4053/long-chain-full.rs similarity index 84% rename from tests/target/issue-4053-long-chain-full.rs rename to tests/target/issue-4053/long-chain-full.rs index 6c55987e0f0..9b4421aa601 100644 --- a/tests/target/issue-4053-long-chain-full.rs +++ b/tests/target/issue-4053/long-chain-full.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-full.rs","range":[4,12]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/long-chain-full.rs","range":[4,12]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/target/issue-4053-long-chain-middle.rs b/tests/target/issue-4053/long-chain-middle.rs similarity index 81% rename from tests/target/issue-4053-long-chain-middle.rs rename to tests/target/issue-4053/long-chain-middle.rs index 752d468ef8d..9966cf5a107 100644 --- a/tests/target/issue-4053-long-chain-middle.rs +++ b/tests/target/issue-4053/long-chain-middle.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-middle.rs","range":[9,9]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/long-chain-middle.rs","range":[9,9]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/target/issue-4053-long-chain-parent.rs b/tests/target/issue-4053/long-chain-parent.rs similarity index 83% rename from tests/target/issue-4053-long-chain-parent.rs rename to tests/target/issue-4053/long-chain-parent.rs index e7aff44ffda..49e822d9401 100644 --- a/tests/target/issue-4053-long-chain-parent.rs +++ b/tests/target/issue-4053/long-chain-parent.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-long-chain-parent.rs","range":[4,4]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/long-chain-parent.rs","range":[4,4]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/target/issue-4053-partial-item.rs b/tests/target/issue-4053/partial-item.rs similarity index 75% rename from tests/target/issue-4053-partial-item.rs rename to tests/target/issue-4053/partial-item.rs index 3a920e0fea9..ebf28abd4f3 100644 --- a/tests/target/issue-4053-partial-item.rs +++ b/tests/target/issue-4053/partial-item.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-partial-item.rs","range":[7,7]},{"file":"tests/source/issue-4053-partial-item.rs","range":[12,13]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/partial-item.rs","range":[7,7]},{"file":"tests/source/issue-4053/partial-item.rs","range":[12,13]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/target/issue-4053-root-absorption-visual.rs b/tests/target/issue-4053/root-absorption-visual.rs similarity index 70% rename from tests/target/issue-4053-root-absorption-visual.rs rename to tests/target/issue-4053/root-absorption-visual.rs index aee9916b374..85ed0f81e4b 100644 --- a/tests/target/issue-4053-root-absorption-visual.rs +++ b/tests/target/issue-4053/root-absorption-visual.rs @@ -1,5 +1,5 @@ // rustfmt-indent_style: Visual -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-root-absorption-visual.rs","range":[5,5]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/root-absorption-visual.rs","range":[5,5]}] fn method_chain(val: Option) { val diff --git a/tests/target/issue-4053-root-absorption.rs b/tests/target/issue-4053/root-absorption.rs similarity index 64% rename from tests/target/issue-4053-root-absorption.rs rename to tests/target/issue-4053/root-absorption.rs index 8d5971f2b9f..6a0c6fde99f 100644 --- a/tests/target/issue-4053-root-absorption.rs +++ b/tests/target/issue-4053/root-absorption.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-root-absorption.rs","range":[4,4]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/root-absorption.rs","range":[4,4]}] fn method_chain(val: Option) { val diff --git a/tests/target/issue-4053-short-chain-full.rs b/tests/target/issue-4053/short-chain-full.rs similarity index 63% rename from tests/target/issue-4053-short-chain-full.rs rename to tests/target/issue-4053/short-chain-full.rs index 0a4c376471b..e97756b9c2d 100644 --- a/tests/target/issue-4053-short-chain-full.rs +++ b/tests/target/issue-4053/short-chain-full.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-full.rs","range":[4,5]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/short-chain-full.rs","range":[4,5]}] fn method_chain(val: Option) { let _ = val.map(|val| val).unwrap(); diff --git a/tests/target/issue-4053-short-chain-middle.rs b/tests/target/issue-4053/short-chain-middle.rs similarity index 67% rename from tests/target/issue-4053-short-chain-middle.rs rename to tests/target/issue-4053/short-chain-middle.rs index 1d7fe791b54..6d8994d49e4 100644 --- a/tests/target/issue-4053-short-chain-middle.rs +++ b/tests/target/issue-4053/short-chain-middle.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-middle.rs","range":[5,5]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/short-chain-middle.rs","range":[5,5]}] fn method_chain(val: Option) { let _ = val diff --git a/tests/target/issue-4053-short-chain-parent.rs b/tests/target/issue-4053/short-chain-parent.rs similarity index 67% rename from tests/target/issue-4053-short-chain-parent.rs rename to tests/target/issue-4053/short-chain-parent.rs index 0770e940813..ec5b1f5f1d7 100644 --- a/tests/target/issue-4053-short-chain-parent.rs +++ b/tests/target/issue-4053/short-chain-parent.rs @@ -1,4 +1,4 @@ -// rustfmt-file_lines: [{"file":"tests/source/issue-4053-short-chain-parent.rs","range":[4,4]}] +// rustfmt-file_lines: [{"file":"tests/source/issue-4053/short-chain-parent.rs","range":[4,4]}] fn method_chain(val: Option) { let _ = val