rust-lang / rust-lang/rustfmt

[Tracking] Formatting failures with all-or-nothing fallback behavior

Open
#6,687 3 comments 1 reaction 1 assignee View on GitHub

@shulaoda is already working on this.

Since Oct 10, 2025.

C-tracking-issue
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

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.