Rustfmt - how to debug indentation bug?

I've the following part of the code...

#[test]
fn queue_write_wait_test() {
    test_rqlited::TEST_RQLITED_DB.run_test(|| {
            let mut q = TEST_CONNECTION
            .execute_queue()
            .set_wait()
            .set_timeout(Duration::from_millis(1000).into())
            .push_sql_str("DROP TABLE IF EXISTS temp.queue_write_wait_test")
            .push_sql_str("CREATE TEMP TABLE IF NOT EXISTS queue_write_wait_test (id INTEGER NOT NULL PRIMARY KEY, name TEXT)");

rustfmt doesn't format this code. "let mut q" is not moved to the left.
It doesn't "touch" the complete closure anylonger, whatever there will be in wrong format.
When I comment out the last push_sql_str-line and add the ; at the end of the line above, it formats the code again.

#[test]
fn queue_write_wait_test() {
    test_rqlited::TEST_RQLITED_DB.run_test(|| {
        let mut q = TEST_CONNECTION
            .execute_queue()
            .set_wait()
            .set_timeout(Duration::from_millis(1000).into())
            .push_sql_str("DROP TABLE IF EXISTS temp.queue_write_wait_test");
        // .push_sql_str("CREATE TEMP TABLE IF NOT EXISTS queue_write_wait_test (id INTEGER NOT NULL PRIMARY KEY, name TEXT)");

I've not found any way to reproduce it with more generic code.

So is there anything I can do to get some debug info of rustfmt, why it thinks that everything is ok?!

It doesn't think that everything is OK. It just isn't able to format code if it will end up with lines more the certain length (and in this case doesn't change the format at all). Not sure if this is intentional, but this is a known issue.

@Cerber-Ursi
But this is not always the case, that long lines break the formatter.

Here Rust Playground
is the line much longer...

It is always the case. In the first example the expression/statement being formatted starts with test_rqlited and in the second example it starts with let _x. In both cases rustfmt can figure out the indentation before the statement/expression properly, but fails to format the expression/statement itself: Rust Playground

No the problem is not the statement itself. But that the whole block/scope isn't formatted. In the sample from the beginning, it is the whole || {...} closure, not only the let mut q with the long line.

The block is not formatted because it is part of the expression that is not formatted: Rust Playground. The long line breaks the formatting for the entire expression, which always happens with long lines.

@Heliozoa That becomes formatted, if it would be compilable code.

But

#[test]
fn queue_write_wait_test() {
    test_rqlited::TEST_RQLITED_DB.run_test(|| {
            let mut q = TEST_CONNECTION
            .execute_queue()
            .set_wait()
            .set_timeout(Duration::from_millis(1000).into())
            .push_sql_str("DROP TABLE IF EXISTS temp.queue_write_wait_test")
            .push_sql_str("CREATE TEMP TABLE IF NOT EXISTS queue_write_wait_test (id INTEGER NOT NULL PRIMARY KEY, name TEXT)");

                    let x = but_this_becomes_not_formatted();
    })
    .this_becomes_formatted();
}

As I said, the effect is, that the whole closure can be formatted like garbage and rustfmt --check has no problem with it.

this_becomes_formatted is not formatted properly. Rustfmt doesn't care about the code being compilable or not because it doesn't try to compile it, only that it's grammatically correct.

Yes, rustfmt is unable to format expressions properly if they contain long lines. If you want an error when this happens you can try setting

error_on_unformatted = true
error_on_line_overflow = true

in your rustfmt.toml. The relevant issue is Gives up on chains if any line is too long. · Issue #3863 · rust-lang/rustfmt · GitHub

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.