rust-lang / rust-lang/rustfmt

First and second operand in series of binops should not be on one line if first operand 4 characters and binop requires surrounding spaces

Open
#6,314 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-binary-ops C-discussion T-style
Dominant language
Rust
Stars
7k
Forks
1.1k
Avg merge
2d 13h
Merged PRs (30d)
24

Description

We have a rule that puts the second operand of a chain on the same line as the first if the first is 4 characters or less:

fn foo() -> Type {
    xxxx.longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong()
        .more()
        .things?
        .others();
}

This rule avoids adding an extra line break when there was room on the same line.

We apply this rule to a series of binops, as well, which gives similarly satisfying results if the first operand is 1-3 characters long:

fn foo() -> Type {
    xxx + longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
        + more
        + things
        + others
}

However, we use the same 4-character threshold, without taking the space before the binop into account:

fn foo() -> Type {
    xxxx + longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
        + more
        + things
        + others
}

We only break to a new line when the first item becomes 5 or more characters long.

I think the rule here should be taking the whitespace before the operator into account, such that the threshold is "4 characters (including any space before the binop)".

I think the underlying rule from the style guide here is:

If the length of the last line of the first element plus its indentation is less than or equal to the indentation of the second line, then combine the first and second lines if they fit. Apply this rule recursively.

Worth noting that that rule is only defined for chains:

A chain is a sequence of field accesses, method calls, and/or uses of the try operator ?. E.g., a.b.c().d or foo?.bar().baz?.

I think it's good that we apply this to binops as well, even though we don't have a style guide rule for that. I think we should capture that generalization in the style guide. However, I also think that generalization needs to take into account whether the operator requires spaces around it (like + or -) or does not (like .).

cc @rust-lang/style

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

Start by tracing rustfmt's handling of chains and binary-operator series, using the examples in the issue to compare operators that require surrounding spaces with those that do not. Done means the four-character case breaks at the correct point, shorter operands retain the compact layout, and the style guide captures the generalized rule.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.