Skip to content

Commit 83b707d

Browse files
committed
Clamp width settings to max_width when entering macro scope
Within a macro scope, max_width is reduced, which can trigger warnings if it is reduced below some other width setting (e.g. struct_lit_width.) Width settings were already being clamped to max_width, but only after the warning fired. A macro scope now clamps the setting to max_width before the warning.
1 parent a2625bf commit 83b707d

File tree

3 files changed

+66
-27
lines changed

3 files changed

+66
-27
lines changed

src/config/config_type.rs

+46-22
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ impl ConfigType for IgnoreList {
6565
}
6666
}
6767

68+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69+
#[allow(unreachable_pub)]
70+
pub enum Clamp {
71+
Yes,
72+
No,
73+
}
74+
6875
macro_rules! create_config {
6976
// Options passed into the macro.
7077
//
@@ -79,6 +86,7 @@ macro_rules! create_config {
7986

8087
use serde::{Deserialize, Serialize};
8188
use $crate::config::style_edition::StyleEditionDefault;
89+
use $crate::config::config_type::Clamp;
8290

8391
#[derive(Clone)]
8492
#[allow(unreachable_pub)]
@@ -112,13 +120,16 @@ macro_rules! create_config {
112120
// with `config.set_option(false)` if we ever get a stable/usable
113121
// `concat_idents!()`.
114122
#[allow(unreachable_pub)]
115-
pub struct ConfigSetter<'a>(&'a mut Config);
123+
pub struct ConfigSetter<'a> {
124+
config: &'a mut Config,
125+
clamp: Clamp,
126+
}
116127

117128
impl<'a> ConfigSetter<'a> {
118129
$(
119130
#[allow(unreachable_pub)]
120131
pub fn $i(&mut self, value: <$ty as StyleEditionDefault>::ConfigType) {
121-
(self.0).$i.2 = value;
132+
self.config.$i.2 = value;
122133
match stringify!($i) {
123134
"max_width"
124135
| "use_small_heuristics"
@@ -129,11 +140,11 @@ macro_rules! create_config {
129140
| "struct_lit_width"
130141
| "struct_variant_width"
131142
| "array_width"
132-
| "chain_width" => self.0.set_heuristics(),
133-
"merge_imports" => self.0.set_merge_imports(),
134-
"fn_args_layout" => self.0.set_fn_args_layout(),
135-
"hide_parse_errors" => self.0.set_hide_parse_errors(),
136-
"version" => self.0.set_version(),
143+
| "chain_width" => self.config.set_heuristics(self.clamp),
144+
"merge_imports" => self.config.set_merge_imports(),
145+
"fn_args_layout" => self.config.set_fn_args_layout(),
146+
"hide_parse_errors" => self.config.set_hide_parse_errors(),
147+
"version" => self.config.set_version(),
137148
&_ => (),
138149
}
139150
}
@@ -159,7 +170,7 @@ macro_rules! create_config {
159170
| "struct_lit_width"
160171
| "struct_variant_width"
161172
| "array_width"
162-
| "chain_width" => self.0.set_heuristics(),
173+
| "chain_width" => self.0.set_heuristics(Clamp::No),
163174
"merge_imports" => self.0.set_merge_imports(),
164175
"fn_args_layout" => self.0.set_fn_args_layout(),
165176
"hide_parse_errors" => self.0.set_hide_parse_errors(),
@@ -226,7 +237,18 @@ macro_rules! create_config {
226237

227238
#[allow(unreachable_pub)]
228239
pub fn set(&mut self) -> ConfigSetter<'_> {
229-
ConfigSetter(self)
240+
ConfigSetter {
241+
config: self,
242+
clamp: Clamp::No,
243+
}
244+
}
245+
246+
#[allow(unreachable_pub)]
247+
pub fn set_clamp(&mut self) -> ConfigSetter<'_> {
248+
ConfigSetter {
249+
config: self,
250+
clamp: Clamp::Yes,
251+
}
230252
}
231253

232254
#[allow(unreachable_pub)]
@@ -256,7 +278,7 @@ macro_rules! create_config {
256278
}
257279
}
258280
)+
259-
self.set_heuristics();
281+
self.set_heuristics(Clamp::No);
260282
self.set_ignore(dir);
261283
self.set_merge_imports();
262284
self.set_fn_args_layout();
@@ -359,7 +381,7 @@ macro_rules! create_config {
359381
| "struct_lit_width"
360382
| "struct_variant_width"
361383
| "array_width"
362-
| "chain_width" => self.set_heuristics(),
384+
| "chain_width" => self.set_heuristics(Clamp::No),
363385
"merge_imports" => self.set_merge_imports(),
364386
"fn_args_layout" => self.set_fn_args_layout(),
365387
"hide_parse_errors" => self.set_hide_parse_errors(),
@@ -423,26 +445,27 @@ macro_rules! create_config {
423445
)+
424446
}
425447

426-
fn set_width_heuristics(&mut self, heuristics: WidthHeuristics) {
448+
fn set_width_heuristics(&mut self, heuristics: WidthHeuristics, clamp: Clamp) {
427449
let max_width = self.max_width.2;
428450
let get_width_value = |
429451
was_set: bool,
430452
override_value: usize,
431453
heuristic_value: usize,
432454
config_key: &str,
433455
| -> usize {
434-
if !was_set {
435-
return heuristic_value;
436-
}
437-
if override_value > max_width {
456+
let value = if !was_set {
457+
heuristic_value
458+
} else {
459+
override_value
460+
};
461+
if clamp == Clamp::No && value > max_width {
438462
eprintln!(
439463
"`{0}` cannot have a value that exceeds `max_width`. \
440464
`{0}` will be set to the same value as `max_width`",
441465
config_key,
442466
);
443-
return max_width;
444467
}
445-
override_value
468+
value.min(max_width)
446469
};
447470

448471
let fn_call_width = get_width_value(
@@ -510,13 +533,14 @@ macro_rules! create_config {
510533
self.single_line_let_else_max_width.2 = single_line_let_else_max_width;
511534
}
512535

513-
fn set_heuristics(&mut self) {
536+
fn set_heuristics(&mut self, clamp: Clamp) {
514537
let max_width = self.max_width.2;
515538
match self.use_small_heuristics.2 {
516539
Heuristics::Default =>
517-
self.set_width_heuristics(WidthHeuristics::scaled(max_width)),
518-
Heuristics::Max => self.set_width_heuristics(WidthHeuristics::set(max_width)),
519-
Heuristics::Off => self.set_width_heuristics(WidthHeuristics::null()),
540+
self.set_width_heuristics(WidthHeuristics::scaled(max_width), clamp),
541+
Heuristics::Max =>
542+
self.set_width_heuristics(WidthHeuristics::set(max_width), clamp),
543+
Heuristics::Off => self.set_width_heuristics(WidthHeuristics::null(), clamp),
520544
};
521545
}
522546

src/config/mod.rs

+19-4
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,21 @@ mod test {
680680
assert_eq!(config.was_set().verbose(), false);
681681
}
682682

683+
#[test]
684+
fn test_clamp_to_max_width() {
685+
let toml = r#"
686+
max_width = 100
687+
struct_lit_width = 200
688+
"#;
689+
let mut config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
690+
assert_eq!(config.struct_lit_width(), config.max_width());
691+
692+
// simulate entering a macro scope
693+
let new = config.max_width() - 4;
694+
config.set_clamp().max_width(new);
695+
assert_eq!(config.struct_lit_width(), config.max_width());
696+
}
697+
683698
const PRINT_DOCS_STABLE_OPTION: &str = "stable_option <boolean> Default: false";
684699
const PRINT_DOCS_UNSTABLE_OPTION: &str = "unstable_option <boolean> Default: false (unstable)";
685700
const PRINT_DOCS_PARTIALLY_UNSTABLE_OPTION: &str =
@@ -1049,10 +1064,10 @@ make_backup = false
10491064
max_width = 100
10501065
"#;
10511066
let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
1052-
assert_eq!(config.array_width(), usize::MAX);
1053-
assert_eq!(config.attr_fn_like_width(), usize::MAX);
1054-
assert_eq!(config.chain_width(), usize::MAX);
1055-
assert_eq!(config.fn_call_width(), usize::MAX);
1067+
assert_eq!(config.array_width(), 100);
1068+
assert_eq!(config.attr_fn_like_width(), 100);
1069+
assert_eq!(config.chain_width(), 100);
1070+
assert_eq!(config.fn_call_width(), 100);
10561071
assert_eq!(config.single_line_if_else_max_width(), 0);
10571072
assert_eq!(config.struct_lit_width(), 0);
10581073
assert_eq!(config.struct_variant_width(), 0);

src/macros.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,7 @@ impl MacroBranch {
13291329
shape.indent.block_indent(&config)
13301330
};
13311331
let new_width = config.max_width() - body_indent.width();
1332-
config.set().max_width(new_width);
1332+
config.set_clamp().max_width(new_width);
13331333

13341334
// First try to format as items, then as statements.
13351335
let new_body_snippet = match crate::format_snippet(&body_str, &config, true) {

0 commit comments

Comments
 (0)