fmt-rfcs icon indicating copy to clipboard operation
fmt-rfcs copied to clipboard

`Chains of fields and method calls` section is maybe underspecified

Open ytmimi opened this issue 1 year ago • 6 comments

Asking this in response to https://github.com/rust-lang/rustfmt/issues/6332.

Not sure if this is a style guide bug, a rustfmt bug, or if the style guide is underspecified (or maybe I'm looking in the wrong section), but the Chains of fields and method calls doesn't fully describe scenarios where the last line of the chain's root isn't indented. For example Foo/foo in the code below:

fn main() {
    Foo {
        field_a: value_a,
        field_b: value_b,
    }
    .call_some_method()
    .do_something(lots, of, arguments)
    .do_another_thing(also, many, arguments);

    foo(
        Some(value_a),
        Some(value_b),
        Some(value_c),
        Some(value_d),
        Some(value_e),
        Some(value_f),
        Some(value_g),
    )
    .call_some_method()
    .do_something(lots, of, arguments)
    .do_another_thing(also, many, arguments);
}

The guide states the following (emphasis mine):

If formatting on multiple lines, put each field access or method call in the chain on its own line, with the line-break before the . and after any ?. Block-indent each subsequent line

Again emphasis mine, and in the Multi-line elements subsection the guide states:

If any element in a chain is formatted across multiple lines, put that element and any later elements on their own lines.

a.b.c()?
    .foo(
        an_expr,
        another_expr,
    )
    .bar
    .baz

Note there is block indent due to the chain and the function call in the above example.

I think the current formatting produced by rustfmt is correct, but the guide uses language that suggests that the chained calls be block indented, so should the Foo/foo example above actually be formatted like this?

fn main() {
    Foo {
        field_a: value_a,
        field_b: value_b,
    }
        .call_some_method()
        .do_something(lots, of, arguments)
        .do_another_thing(also, many, arguments);

    foo(
        Some(value_a),
        Some(value_b),
        Some(value_c),
        Some(value_d),
        Some(value_e),
        Some(value_f),
        Some(value_g),
    )
        .call_some_method()
        .do_something(lots, of, arguments)
        .do_another_thing(also, many, arguments);
}

ytmimi avatar Sep 19 '24 17:09 ytmimi