[Tracking] Formatting failures with all-or-nothing fallback behavior
@shulaoda is already working on this.
Since Oct 10, 2025.
- Dominant language
- Rust
- Stars
- 7k
- Forks
- 1.1k
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 24
Description
Summary
When rustfmt encounters an unformattable element in a statement (e.g., long strings exceeding max_width, insufficient macro formatting support, problematic block comments), it abandons formatting the entire statement instead of attempting partial formatting. This all-or-nothing fallback behavior results in:
- Unformatted statements (original source preserved verbatim)
- Trailing whitespace errors (
error[internal]: left behind trailing whitespace)
Root Cause
Rustfmt expects to successfully rewrite every element in a statement. When any single element cannot be formatted, the entire statement formatting is aborted and the original source is preserved verbatim. This affects various constructs including method chains (in src/chains.rs), match expressions, and other complex statements.
The problem is that rustfmt currently has no graceful degradation strategy when it cannot format part of a statement. The team is actively working on improving this behavior.
Examples
1. Method chains with long string arguments (#3863)
// Input: Chain with one long string argument
foo("short").long("very long text that exceeds max width").baz().collect();
// Expected: Wrapped across lines (with format_strings=true)
foo("short")
.long(
"very long text that exceeds max \
width",
)
.baz()
.collect();
// Actual: Preserved as-is, entire chain unformatted
// Workaround: Set format_strings=true
2. Macro chains with trailing whitespace (#6649)
// Input: Macro chain with internal formatting issues
bolero::check!()
.with_type::<FlowKey>()
.for_each(|x| {
let a = 1;
⎵⎵⎵⎵ // ← trailing whitespace preserved
let very_long_line = "exceeds max_width...";
});
// Issue: Long string causes chain formatting to fail → fallback preserves trailing whitespace → error[internal]
// Workaround: Manually remove trailing whitespace before running rustfmt or set format_strings=true
3. Macros with unusual formatting (#6659)
// Input: Closure with macro containing excessive whitespace
true.then(|| {⎵⎵ // ← trailing whitespace preserved
println! { "{}",
0
};
});
// Issue: Insufficient macro formatting support causes entire statement to fall back → trailing whitespace preserved → error[internal]
// Workaround: Manually reformat the macro or remove trailing whitespace
4. Match expressions with block comments (#6663)
// Input: Match expression with block comment after scrutinee
fn main() {
match () /*x*/ {
// ^^^^^ Culprit. Remove the x, or replace the whole blockcomment with spaces and it'll format
⎵⎵⎵⎵ // ← trailing whitespace preserved
_ => {}
}
}
// Issue: Block comment causes match expression formatting to fail → fallback preserves trailing whitespace → error[internal]
// Workaround: Remove the block comment or manually remove trailing whitespace
Related Issues
- #3863
- #6649
- #6659
- #6663
- https://github.com/rust-lang/rustfmt/issues/6634
Workarounds
Most cases are caused by long string arguments. Setting format_strings = true in rustfmt.toml (requires nightly version) allows rustfmt to format long strings, preventing the chain formatting fallback. Alternatively, manually remove trailing whitespace before running rustfmt.
Note that some of these issues can be directly resolved by fixing specific formatting bugs (e.g., block comment handling), while others may require significant long-term improvements to the formatting infrastructure (e.g., graceful degradation for long strings).
References
Please feel free to modify the description to make it easier to understand or more accurate. If it's not necessary, please feel free to close it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.