Fix struct comment_width off-by-one error - #7078
Conversation
|
List formatting is used all over the codebase. Does this same off-by-one error exist elsewhere? |
I cannot say confidently. The use of EvidenceHowever, I consider the bug described in #6180 to be inherent to Having said that,
The test case added by this PR covers the first call site. The test case that had to be adjusted fell out of the second call site. If you would prefer, I could add a more thorough test for the second call site, one that resembles the one added by this PR with 99-, 100-, and 101-column boundary coverage. |
Fixes #6180.
The bug
The bug originates here, in
rewrite_aligned_items_inner:rustfmt/src/vertical.rs
Line 216 in 7852ca3
Note the use of
sub_width_opt(1), which reserves space for the item separator (e.g., a comma).That declared
item_shapeis used to construct aListFormattingstruct, which is used in a call towrite_list:rustfmt/src/vertical.rs
Lines 265 to 269 in 7852ca3
Note that
item_shapepopulates theshapefield of theListFormattingstruct viaListFormatting::new:rustfmt/src/lists.rs
Lines 38 to 51 in 7852ca3
Within the body of
write_list, there is this code:rustfmt/src/lists.rs
Lines 369 to 370 in 7852ca3
But recall that
formatting.shape = item_shape, which already (and incorrectly for a comment) has space reserved for the separator, hence, the off-by-one error.The fix
The fix is to add an additional, optional field,
pre_comment_shape, toListFormatting. This additional field does not reserve space for the separator, and thus avoids the off-by-one error.In particular, the call to
rewrite_commentinwrite_listnow looks like this:The field is optional because not all code paths that construct a
ListFormattinguse it. Specifically,pre_comment_shapeis set inrewrite_aligned_items_inner, but it is not set at any ofListFormatting::new's other call sites.Tests
A test case was added to resemble the one in #6180. However, it was modified to obtain 99-, 100-, and 101-column boundary coverage.
Also, one other existing test case had to be modified, as it suffered from the same bug. Specifically, this code:
rustfmt/tests/target/configs/struct_field_align_threshold/20.rs
Lines 323 to 325 in 7852ca3
was reflowed like this:
What this PR does not do
This PR's test case uses a
comment_widthequal to the defaultmax_width(i.e., 100).By doing so, this PR does not attempt to establish a policy for when
comment_width < max_width, for example.This choice was intentional, as I consider such policy decisions out of scope for this PR.
LLM disclosure
Codex was used to diagnose the bug and implement the fix, including comments I asked it to add to the code; however, all such comments look reasonable to me.
This PR description was written entirely by me (@smoelius).