pmt fmt needs two passes to settle on one input shape: a line comment written between a statement's stacked labels and its command. The second pass is stable, so the output is correct — but pmt fmt --check reports a change on a file that has already been formatted, and format-on-save leaves the buffer dirty for one extra round.
Reproduction
main() {
1:
// mid
2: left;
}
pass 1: "main() {\n 1: 2: // mid\n left;\n}\n"
pass 2: "main() {\n 1: 2:\n // mid\n left;\n}\n"
pass 3: identical to pass 2
Pass 1 restacks the labels and pulls the comment up as a trailing comment on the label line, which pushes the command to column 8. Pass 2 sees the restacked labels, decides the comment is an own-line one after all, and settles.
Scope — narrower than it looks
Only the // form, and only between stacked labels and the command. These three neighbours are all idempotent on the first pass:
main() {\n 1:\n /* mid */\n 2: left;\n}\n block comment -> stable
main() {\n 1:\n // mid\n left;\n}\n single label -> stable
main() {\n // mid\n 1: left;\n}\n comment above -> stable
Not a regression
This is inherited, not introduced by the green-tree formatter. The pre-green printer produces byte-identical pass-1 and pass-2 output on the same input, verified against a build of it. The behavior is pinned by a two-pass fixture so it cannot drift silently, and the idempotence claim in the repo's own notes carries the exception.
Why it is worth fixing anyway
fmt --check is meant to answer "is this file formatted?" and on this shape it answers no about a file that is. Anything wiring --check into CI or a pre-commit hook sees a failure with no user-applicable fix other than running fmt twice.
Where to look
The interaction is between label restacking and trailing-comment attribution: on pass 1 the labels are still on separate lines when the comment's role is decided, so it qualifies as same-line trailing; after restacking it no longer does. A fix likely means deciding the comment's role against the layout the printer is about to produce rather than the one it read — or accepting the pass-1 shape as canonical and making pass 2 agree with it instead.
Whichever direction, the property suite in crates/post-machine/tests/fmt_property.rs currently EXCLUDES this shape from generation with the reason recorded; that exclusion comes out as part of the fix, and its removal is the test that the fix worked.
pmt fmtneeds two passes to settle on one input shape: a line comment written between a statement's stacked labels and its command. The second pass is stable, so the output is correct — butpmt fmt --checkreports a change on a file that has already been formatted, and format-on-save leaves the buffer dirty for one extra round.Reproduction
Pass 1 restacks the labels and pulls the comment up as a trailing comment on the label line, which pushes the command to column 8. Pass 2 sees the restacked labels, decides the comment is an own-line one after all, and settles.
Scope — narrower than it looks
Only the
//form, and only between stacked labels and the command. These three neighbours are all idempotent on the first pass:Not a regression
This is inherited, not introduced by the green-tree formatter. The pre-green printer produces byte-identical pass-1 and pass-2 output on the same input, verified against a build of it. The behavior is pinned by a two-pass fixture so it cannot drift silently, and the idempotence claim in the repo's own notes carries the exception.
Why it is worth fixing anyway
fmt --checkis meant to answer "is this file formatted?" and on this shape it answers no about a file that is. Anything wiring--checkinto CI or a pre-commit hook sees a failure with no user-applicable fix other than runningfmttwice.Where to look
The interaction is between label restacking and trailing-comment attribution: on pass 1 the labels are still on separate lines when the comment's role is decided, so it qualifies as same-line trailing; after restacking it no longer does. A fix likely means deciding the comment's role against the layout the printer is about to produce rather than the one it read — or accepting the pass-1 shape as canonical and making pass 2 agree with it instead.
Whichever direction, the property suite in
crates/post-machine/tests/fmt_property.rscurrently EXCLUDES this shape from generation with the reason recorded; that exclusion comes out as part of the fix, and its removal is the test that the fix worked.