diff --git a/src/config/config_type.rs b/src/config/config_type.rs index afac8d3fcf9..701cd58c2ac 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -423,6 +423,63 @@ macro_rules! create_config { )+ } + /// Reduces the maximum width of the configuration. + /// + /// This method is intended to be used when creating a forked + /// configuration for a particular formatting context in which the + /// total available width needs to be reduced. This reduces the + /// size of max_width, and all other properties affected by small + /// heuristics, without treating those adjustments as overrides. + /// + /// As an example use case, this method is used when formatting + /// arms within a declarative macro. + #[allow(unreachable_pub)] + pub fn reduce_max_width(&mut self, delta: usize) { + self.adjust_max_width(-1 * delta as isize); + } + + /// Increases the maximum width of the configuration. + /// + /// This method is intended to be used when creating a forked + /// configuration for a particular formatting context in which the + /// total available width needs to be reduced. This reduces the + /// size of max_width, and all other properties affected by small + /// heuristics, without treating those adjustments as overrides. + /// + /// As an example use case, this method is used when formatting + /// arms within a declarative macro. + #[allow(unreachable_pub)] + pub fn increase_max_width(&mut self, delta: usize) { + self.adjust_max_width(delta as isize); + } + + /// Adjusts the maximum width of the configuration. + /// + /// This method is intended to be used when creating a forked + /// configuration for a particular formatting context in which the + /// total available width needs to be reduced. This reduces the + /// size of max_width, and all other properties affected by small + /// heuristics, without treating those adjustments as overrides. + /// + /// As an example use case, this method is used when formatting + /// arms within a declarative macro. + fn adjust_max_width(&mut self, delta: isize) { + let adjust = |value: usize| (value as isize + delta) as usize; + + self.array_width.2 = adjust(self.array_width.2); + self.attr_fn_like_width.2 = adjust(self.attr_fn_like_width.2); + self.chain_width.2 = adjust(self.chain_width.2); + self.fn_call_width.2 = adjust(self.fn_call_width.2); + self.single_line_if_else_max_width.2 = adjust(self.single_line_if_else_max_width.2); + self.single_line_let_else_max_width.2 = + adjust(self.single_line_let_else_max_width.2); + self.struct_lit_width.2 = adjust(self.struct_lit_width.2); + self.struct_variant_width.2 = adjust(self.struct_variant_width.2); + + self.max_width.2 = adjust(self.max_width.2); + self.set_heuristics(); + } + fn set_width_heuristics(&mut self, heuristics: WidthHeuristics) { let max_width = self.max_width.2; let get_width_value = | diff --git a/src/macros.rs b/src/macros.rs index 2d56021069c..c620e14ecd4 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1339,15 +1339,13 @@ impl MacroBranch { } else { shape.indent.block_indent(&config) }; - let new_width = config.max_width() - body_indent.width(); - config.set().max_width(new_width); + config.reduce_max_width(body_indent.width()); // First try to format as items, then as statements. let new_body_snippet = match crate::format_snippet(&body_str, &config, true) { Some(new_body) => new_body, None => { - let new_width = new_width + config.tab_spaces(); - config.set().max_width(new_width); + config.increase_max_width(config.tab_spaces()); match crate::format_code_block(&body_str, &config, true) { Some(new_body) => new_body, None => { diff --git a/tests/source/issue-6651/custom_width.rs b/tests/source/issue-6651/custom_width.rs new file mode 100644 index 00000000000..b6bbe715290 --- /dev/null +++ b/tests/source/issue-6651/custom_width.rs @@ -0,0 +1,21 @@ +// rustfmt-format_macro_bodies: true +// rustfmt-max_width: 82 +// rustfmt-fn_call_width: 76 + +macro_rules! short { + () => { + m!(a, b, c); + }; +} + +macro_rules! medium { + () => { + m!(aaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbb, cccccccccccccccc, ddddddddd); + }; +} + +macro_rules! long { + () => { + m!(aaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbb, cccccccccccccccc, ddddddddddddddd); + }; +} diff --git a/tests/source/issue-6651/default.rs b/tests/source/issue-6651/default.rs new file mode 100644 index 00000000000..de8e64b4094 --- /dev/null +++ b/tests/source/issue-6651/default.rs @@ -0,0 +1,19 @@ +// rustfmt-format_macro_bodies: true + +macro_rules! short { + () => { + m!(a, b, c); + }; +} + +macro_rules! medium { + () => { + m!(aaaaaaaaaa, bbbbbbbbbb, cccccccccc, ddddddddd); + }; +} + +macro_rules! long { + () => { + m!(aaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbb, cccccccccccccccc, ddddddddddddddd); + }; +} diff --git a/tests/target/issue-6651/custom_width.rs b/tests/target/issue-6651/custom_width.rs new file mode 100644 index 00000000000..b46bd5ef5cc --- /dev/null +++ b/tests/target/issue-6651/custom_width.rs @@ -0,0 +1,26 @@ +// rustfmt-format_macro_bodies: true +// rustfmt-max_width: 82 +// rustfmt-fn_call_width: 76 + +macro_rules! short { + () => { + m!(a, b, c); + }; +} + +macro_rules! medium { + () => { + m!(aaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbb, cccccccccccccccc, ddddddddd); + }; +} + +macro_rules! long { + () => { + m!( + aaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbb, + cccccccccccccccc, + ddddddddddddddd + ); + }; +} diff --git a/tests/target/issue-6651/default.rs b/tests/target/issue-6651/default.rs new file mode 100644 index 00000000000..6fab41d9018 --- /dev/null +++ b/tests/target/issue-6651/default.rs @@ -0,0 +1,24 @@ +// rustfmt-format_macro_bodies: true + +macro_rules! short { + () => { + m!(a, b, c); + }; +} + +macro_rules! medium { + () => { + m!(aaaaaaaaaa, bbbbbbbbbb, cccccccccc, ddddddddd); + }; +} + +macro_rules! long { + () => { + m!( + aaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbb, + cccccccccccccccc, + ddddddddddddddd + ); + }; +}