rust-lang / rust-lang/rustfmt

Option for keeping closing brackets on the same line

Open
#5,972 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

I would like an option so that closing brackets of method calls and of closures would be on the same line as the last parameter or expression. Example:

fn activity(stuff: Vec<A>) -> Vec<B> {
    stuff.iter()
        .map(|thing| {
            thing
                .method(
                    a,
                    b)})
        .collect()
}

Here, the closing brackets of calling method, calling map and its closure are on the same line as b.

On the contrary, rustfmt formats it like this:

fn activity(stuff: Vec<A>) -> Vec<B> {
    stuff.iter()
        .map(|thing| {
            thing
                .method(
                    a,
                    b,
                )
        })
        .collect()
}

There are two lines with only brackets, so not much content, which is undesirable.

Not indent_style = "Visual"

indent_style = "Visual" causes that closing brackets are on the same line, but its main point is that it keeps the first item on the same line as the opening bracket and aligns other items to the first item using spaces. Alignment with spaces is not viable for me because I use a proportional typeface, and spaces are narrower than most characters.

function(
    a,
    b,
    c); // right

function(a,
         b,
         c); // wrong

The second case looks to me like this:

function(a,
         b,
         c); // wrong

Extent

That closing brackets would be on the same line should happen with function calls and closures (at least in methods like map). I prefer it not with array literals and struct constructors, but I can accept both options. But it should not happen with modules, impl blocks, and top-level functions (unless they have one-line body) because they are often long and things are appended at the end of them.

let array = [
    1,
    2,
] // preferred

let array = [
    1,
    2] // passable
function1(
    function2(|param| {
        function3(
            thing)})) // right

function1(
    function2(|param| {
        function3(
            thing
        )
    })
) // wrong
mod things {
    impl Thing {
        fn do() {
            doing1();
            doing2();
        }
    }
} // right

mod things {
    impl Thing {
        fn do() {
            doing1();
            doing2(); }}} // wrong

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 reproducing the issue's examples with rustfmt and tracing how it formats multiline method calls and closures. Define the option's behavior against the stated exclusions for arrays, structs, modules, impl blocks, and top-level functions. Done means the requested bracket placement is configurable and the examples are covered by formatter tests.

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
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.