rust-lang / rust-lang/rustfmt

Modified indentation policy for wrapped expressions (with focus on conditions)

Open
#4,818 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-binary-ops C-feature-request P-low
Dominant language
Rust
Stars
7k
Forks
1.1k
Avg merge
2d 13h
Merged PRs (30d)
24

Description

📋 Description

This is something I have used in my C code back in the 80s and have been struggling to get code formatters to do ever since (with varying levels of success).

The general rule is: indent the wrapped lines so that operands at the same level in the expression tree have the same indentation; nested operations are "more indented". For best results, when wrapping long lines, parenthesis are always used to clarify the evaluation order and ensure "nested" operations are more indented. This makes a lot of sense for boolean operators anyway (quick, what does a && b || c do?).

For example, in if statements:

if some_condition
&& another_condition
{
    code...
}

if (some_condition
 && another_condition)
|| yet_another_condition
{
    code...
}

if (some_condition
 && another_condition)
|| (yet_another_condition
 && final_condition)
{
    code...
}

This makes the structure of the condition very clear. Compare with the current formatting where the indentation level is actively misleading:

if some_condition
    && another_condition
{
    code... // is indented the same level as the condition, so wasting a line for { is required
}

if (some_condition
    && another_condition)
    || yet_another_condition
{
    // Misleading, another_condition and yet_another_condition have same indentation
}

if (some_condition
    && another_condition)
    || (yet_another_condition
        && final_condition)
{
    // Misleading again; also, symmetric structure of statement is not apparent
}

The proposal generalizes to while statements as follows:

while some_condition
   && (another_condition
    || yet_another_condition)
{
    code...
}

Ideally, I'd love to see this approach be extended to wrapping long expressions in general:

fn foo() -> bool {
    let bar = some_condition
           && another_condition;
       some_condition
    && another_condition
}

And apply this to other operators as well:

fn foo() -> usize {
    let bar = some_value
            + (another_value
             * yet_another_value)
            - final_value;
      some_value
    + (another_value
     * yet_another_value)
    - final_value
}

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.

Research direction

The issue names no files, tests, or entry points. Start from the current formatting behavior shown in the examples and determine how the proposed indentation should apply to conditions and other wrapped expressions; done means the formatter produces the requested tree-aligned indentation consistently.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.