rust-lang / rustfmt

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

Weird behavior with parameters `chain_width` and `use_small_heuristics` #6389

Closed 0hDEADBEAF closed 2 weeks ago

0hDEADBEAF commented 2 weeks ago

I've experienced an odd behavior with rustfmt parameter chain_width. I'm using the following rustfmt.toml file:

use_small_heuristics = "Off"

When invoking the command cargo fmt on the following code:

struct Foo {
    bar: String,
}

impl Foo {
    fn new(bar: &str) -> Self {
        Self {
            bar: bar.to_string(),
        }
    }

    fn test1(&self) -> &Self {
        self
    }
    fn test2(&self) {
        println!("{}", self.bar);
    }
}

fn main() {
    // The following line is actually uncommented
    // Foo::new("Hello world! This is just a loooooooong string.").test1().test2();
}

Then the line Foo::new("Hello world! This is just a loooooooong string.").test1().test2(); doesn't get changed.

However, if I add chain_width = 60 to the rustfmt.toml file and invoke cargo fmt again, the line gets modified to:

Foo::new("Hello world! This is just a loooooooong string.")
        .test1()
        .test2();

This is odd to me since, according to the documentation (see here), 60 is the default value for the parameter chain_width. So I was expecting to get the same result but that's not the case. Am I missing something? Is the documentation updated?

From my quick investigation, I narrowed down the problem to what seems a conflict between the parameters use_small_heuristics and chain_width. When I comment out the line use_small_heuristics = "Off" in my rustfmt.toml file, explicitely setting the chain_width value to 60 or not specifying it at all gives the same result, which seems to me like a normal behavior.

This happens whether I'm using cargo fmt and cargo +nightly fmt. I have the following rustfmt versions:

$ cargo fmt --version
rustfmt 1.7.1-stable (f6e511ee 2024-10-15)
$ cargo +nightly fmt --version
rustfmt 1.8.0-nightly (b91a3a0560 2024-11-07)
ytmimi commented 2 weeks ago

@0hDEADBEAF thanks for reaching out. I can totally understand the confusion, and I think it might be helpful to improve the documentation around use_small_heuristics=Off.

Setting use_small_heuristics=Off disables the width settings by setting chain_width to usize::Max, and that's why the chain doesn't get wrapped.

https://github.com/rust-lang/rustfmt/blob/777e25a8c91af9923ad356eb4448ac2ed15167a9/src/config/config_type.rs#L519

https://github.com/rust-lang/rustfmt/blob/777e25a8c91af9923ad356eb4448ac2ed15167a9/src/config/options.rs#L256-L267

However, when you explicitly set chain_width=60, that overrides the use of use_small_heuristics=Off for the chain_width setting.

0hDEADBEAF commented 2 weeks ago

Oh ok! Makes sense now, thank you :D