Rustfmt: Unclear error message: Rustfmt failed … line exceeded maximum length (sorry)

Created on 26 Jun 2016  ·  25Comments  ·  Source: rust-lang/rustfmt

This error message doesn't tell me what are the consequences, and what can I do to avoid the problem.

Does "Rustfmt failed" mean the file could not be parsed and has not been formatted at all, or did it just skip that one line?

Is that a bug/limitation of rustfmt, or a lint telling me to format code better?

What's the maximum length? Can I configure it?

I've got these errors pointing to a few lines that only contain comments, and are 100-109 characters long. I'm confused, because it doesn't seem like an excessive line length that could cause a tool to fail.

Most helpful comment

I guess I would suggest that it should be considered a bug. :)

All 25 comments

rustfmt apparently has a default maximum line length that it'll parse of 100 characters. if you set max_width in rustfmt.toml to a larger number, it'll parse lines up to that length.

ex: ''max_width = 140''

Yeah, we should word this message better. What it means is that Rustfmt couldn't satisfy all the constraints it was given for a line of code. I.e., that it must start at a certain column and be less than the max width. The way to fix it is to manually make the line shorter, usually by factoring out a variable, or manually formatting the line if it is something Rustfmt chokes on (some macros, comments). Put another way, Rustfmt failed in its mission, it's not that execution failed.

The max line length is the maximum Rustfmt is allowed to use, not the maximum that it will parse.

Hmm, @nrc, is there a plan to eventually make it so that rustfmt guarantees X-char output (short of some identifier that is too long or something?) It seems like it ought to be _possible_.

We kind of already do and this error message is about a failure to satisfy that guarantee. We could improve on this (better handling of comments, more aggressive fallbacks) but that seems like a step along a spectrum rather than a categorical change.

@nrc I guess what I meant is, is it considered a bug (if a low priority one) that rustfmt sometimes fails to deliver on the guarantee?

In some cases, yes, but in general, no.

I guess I would suggest that it should be considered a bug. :)

I agree that there is both a minimum possible width and there are unsolvable cases (e.g. very long identifiers, which I mentioned). But in the absence of those it seems like it's be nice to have rustfmt respect a maximum line length constraint. Consider the needs of existing projects like rust that have a maximum line length rule? That said it seems like a low priority thing, at least if today it mostly works.
On Jul 1, 2016 05:56, Caleb Jones [email protected] wrote:@nikomatsakis take, for example, max_width = 1, how should rustfmt then format something like

let a = 1;

when lines are only allowed to be 1 character long? That's why it can't be a bug in general.

—You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub, or mute the thread.

To add to this I have been having some issues related to this error too.

  • Error triggers on long comment lines that cannot be split (such as long urls I'm linking)
  • A string is being formatted to be too long which then causes the error, this is the code:
mod tests {
    #[test]
    fn test_display_formatting() {
        let first_matrix = Matrix::new(2, 3, vec![1, 2, 3, 4, 5, 6]);
        let first_expectation = "⎡1 2 3⎤\n⎣4 5 6⎦";
        assert_eq!(first_expectation, format!("{}", first_matrix));

        let second_matrix = Matrix::new(4,
                                        3,
                                        vec![3.14, 2.718, 1.414, 2.503, 4.669, 1.202, 1.618,
                                             0.5772, 1.3, 2.68545, 1.282, 10000.]);
        // This string is formatted to be too long and makes rustfmt fail.
        let second_expectation = "⎡   3.14   2.718   1.414⎤\n⎢  2.503   4.669   1.202⎥\n⎢  1.618  \
                                  0.5772     1.3⎥\n⎣2.68545   1.282   10000⎦";
        assert_eq!(second_expectation, format!("{}", second_matrix));
    }
}

I imagine this is probably user error - but I am using only the default settings. These errors started cropping up when I installed the latest build today.

There are diference beetween "lenght" of english(ASCII) and non english(UTF-8) strings,
is ok, if my comments in english language,
but if a comment in russian(less letters) i have error: line exceeded maximum length.

@chessnokov yeah, unfortunately there are big problems in Rustfmt with utf8 strings where a char width is > 1 byte. It's a big job to fix, but once we have an initial release out the way it will be a high priority.

On a related note, I'm surprised it doesn't trim leading spaces to give me proper indentation - it's something I'm well used to in the Java world.

That is, if I've got something like this:

fn main() {
    let a = "";
                                let b = "";
            let c = "";
}

I would have like rustfmt to trim the leading spaces and produce

fn main() {
    let a = "";
    let b = "";
    let c = "";
}

rather than the current behaviour of just shrugging its shoulders and telling me the line is too long (if you don't think this is related, I'm happy to raise a new issue to discuss if this is something you want to do).

@ipsi this is kind of weird, it really should fix that. The example you've given does in fact get formatted exactly as you would like. Could you give an example where it doesn't work please?

@nrc Ahh, I think it's specific to macro definitions. Thus:

macro_rules! custom_error {
          (. . .) => (
        .
        .
        .
    )
}

Doesn't get formatted to

macro_rules! custom_error {
    (. . .) => (
        .
        .
        .
    )
}

But regular Rust code _does_. This is with rustfmt 0.6.0 ().

Ok, yeah, we can't format macro defs very well, that is something of a difficult thing to fix. I do have a plan, but it is a big job.

my code got this error message too. both play.rust-lang.org and local rustfmt 0.6.2
https://is.gd/mDnYMN

Fails to format

fn main() {
    let i = 0;
    {
        match (&i, &0) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    {
                        std::rt::begin_panic_fmt(&::std::fmt::Arguments::new_v1({
                            static __STATIC_FMTSTR: &'static [&'static str] =
                            &["assertion failed: `(left == right)` (left: `", "`, right: `", "`)"];
                            __STATIC_FMTSTR
                        }, &match (&left_val, &right_val) {
                            (__arg0, __arg1) =>
                                [::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt),
                                 ::std::fmt::ArgumentV1::new(__arg1, ::std::fmt::Debug::fmt)],
                        }), {
                            static _FILE_LINE: (&'static str, u32) = ("test.rs", 3u32);
                            &_FILE_LINE
                        })
                    }
                }
            }
        }
    };
}

which is expanded assert! macro.

This definitely needs a clearer error message.

Some of my TODO comments contain long URLs that I don't want to make more fragile by feeding to a 3rd-party shortener and, when I received this message the first time I tried rustfmt...

  1. My first impression was that the process had been aborted with no formatting occurring (ie. Some kind of "mistook half the file for a single long line and exhausted some fixed-length buffer while parsing" bug)
  2. When I checked my git status, I then worried it had been left in an in-between state
  3. I didn't relax until I read this thread

This also fails rather than placing the { on the following line as proposed in the struct declaration RFC (https://github.com/rust-lang-nursery/fmt-rfcs/pull/53). Albeit this is a tiny edge case.

struct Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo {
    a: A,
    b: B,
}

Also this case (which is not as small a case), the type is not put on a newline and indented as proposed:

struct Foo {
    a: A,
    longnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaame: LooooooooooooooooooooooooooooooongName,
}

Is there any way to temporarily increase the limit (say to 1000 or 10000 bytes)? This limit makes it virtually impossible to put any amount of unicode in the source.

Alternatively, is there a place where the rustfmt timeline is noted or discussed? I've tried looking for one, but haven't found anything. It seems like with the RFC process an "initial release" could be indefinitely far off, and this issue comes up a lot (#1770, #1451, #1298, #1651, #1447, #6)

Alternatively, is there a place where the rustfmt timeline is noted or discussed?

I hope to have a 1.0 release shipping on the stable Rustup channel around the end of the year (depends a lot on difficulties getting in to the Rust CI, etc.). I intend to make a tracking issue for that soon, and tackling this issue will definitely be on it.

Potentially some of these discussion points should be split off into separate issues?

  1. The error message is confusing, as @ssokolow mentioned, and should probably be changed.
  2. Once std::str::Graphemes is stabilized, potentially use that to deal with counting the graphemic length of Unicode strings.
  3. Formatting long comments and doc comments should be trivial in the prevalent special case where max_width is more than the length of the longest word + 3 (//␣)or 4(///␣ or //!␣).

Would it make sense to have preffered_width that rustfmt would try to get within, but if it can't it would make the line as short as possible and still continue formatting the rest of the block?

My current workaround is to run rustfmt several times, gradually decreasing max_width towards my preffered_width.

The fact that rustfmt faints on every longer-than-expected line without explicitly setting a length in rustfmt.toml keeps away from taking it seriously. I'd even accept leaving exceeding lines as-is.

One case where it's not possible for rustfmt to succeed in reducing the line length is where there's a bytestring for a test vector. It would be nice for rustfmt not to error out when it's not possible to break up a long line.

Was this page helpful?
0 / 5 - 0 ratings