rust-lang / rustfmt

Format Rust code
https://rust-lang.github.io/rustfmt/
Apache License 2.0
6.06k stars 892 forks source link

rustmft 0.9.0-beta splits line needlessly #2903

Open tspiteri opened 6 years ago

tspiteri commented 6 years ago

Version: rustfmt 0.9.0-beta (69ad879 2018-07-27)

This code is unchanged with 0.8.2:

fn foo() {
    let some_variable_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = bar(a).baz(b)?;
}

With 0.9.0-beta, it becomes:

fn foo() {
    let some_variable_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx =
        bar(a).baz(b)?;
}

It is not clear to me why the line is split; it is only 99 characters long.

ytmimi commented 2 years ago

confirming this is still reproducible on rustfmt 1.5.1-nightly (a7bf0090 2022-07-17)

@calebcartwright I know chains are a fairly tricky part of the codebase, but just wanted to walk you through what I found and get your thoughts.

I believe the issue can be tracked down to ChainFormatterShared::format_last_child.

first we include the number of tries when computing almost_total

https://github.com/rust-lang/rustfmt/blob/a7bf0090347d8523dd62c0508a4c8413cdba099a/src/chains.rs#L566-L573

We also subtract the number of tries when computing the last_shape

https://github.com/rust-lang/rustfmt/blob/a7bf0090347d8523dd62c0508a4c8413cdba099a/src/chains.rs#L584-L590

And lastly to compute the one_line_shape we then offset the width by the almost_total, thereby double counting the tries.

https://github.com/rust-lang/rustfmt/blob/a7bf0090347d8523dd62c0508a4c8413cdba099a/src/chains.rs#L596-L602