Skip to content

rustfmt fails to format a specific match statement #3206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rgeorgiev583 opened this issue Nov 18, 2018 · 4 comments · Fixed by #4246
Closed

rustfmt fails to format a specific match statement #3206

rgeorgiev583 opened this issue Nov 18, 2018 · 4 comments · Fixed by #4246

Comments

@rgeorgiev583
Copy link

rgeorgiev583 commented Nov 18, 2018

I couldn't manage to isolate the specific bug in this case, so I'm going to provide the definition of the function containing the match statement as-is:

#[derive(Debug)]
enum Error<'a> {
    RuntimeError(&'a str),
    IoError(io::Error),
}

impl<'a> std::error::Error for Error<'a> {
    fn source(&self) -> Option<&(std::error::Error + 'static)> {
        match self {
            Error::IoError(error) => Some(error),
            _ => None,
        }
    }
}

impl<'a> Display for Error<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match self {
            Error::RuntimeError(description) => write!(f, "runtime error: {}", description),
            Error::IoError(error) => write!(f, "I/O error: {}", error),
        }
    }
}

impl<'a> From<std::io::Error> for Error<'a> {
    fn from(error: io::Error) -> Self {
        Error::IoError(error)
    }
}

type Result<'a, T> = std::result::Result<T, Error<'a>>;

enum Value {
    Str(String),
    Bool(bool),
    Number(Float),
}

impl Display for Value {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        match self {
            Value::Str(value) => write!(f, "{}", value),
            Value::Bool(value) => write!(f, "{}", value),
            Value::Number(value) => write!(f, "{}", value),
        }
    }
}

enum InputMode {
    Disabled,
    Simple(String),
    Nested(usize, String),
}

struct State {
    stack: Vec<Value>,
    input_mode: InputMode,
}

enum ArithmeticOperation {
    Addition,
    Subtraction,
    Multiplication,
    Division,
    Remainder,
}

fn apply_arithmetic_operation<'a>(op: ArithmeticOperation, state: &mut State) -> Result<'a, ()> {
    match       (       state.stack.pop           (),       state.stack.pop      ()                   )





    {
                    (Some(value1), Some(value2)) => {



                        match (value1, value2) {
                        (Value::Number(num1), Value::Number(num2)) => {
                            let result = match op {
                                ArithmeticOperation::Addition => num1 + num2,
                                ArithmeticOperation::Subtraction => num1 - num2,
                                ArithmeticOperation::Multiplication => num1 * num2,
                                    ArithmeticOperation::Division => num1 /num2,
                                ArithmeticOperation::Remainder => num1 % num2,
                            };
                            state.stack.push(Value::Number(result));
                            Ok(())
                        }
                        _ =>
                    Err(Error::RuntimeError(
                        "cannot sum values on top of stack: the two topmost values on the stack should be numbers",
                    ))
                    }}
                    _ =>
                                                return Err(Error::RuntimeError(
                        "cannot sum values on top of stack: there must be at least two values on the stack",
                    ))
                }
}

rustfmt seems to properly format that except for the whole outermost match statement where the whitespace still remains garbled.

@topecongiro
Copy link
Contributor

A smaller example:

fn foo(input: Option<usize>) -> usize {
    match x {
                _ =>
                    Err(Error::RuntimeError(
                        "cannot sum values on top of stack: the two topmost values on the stack should be numbers",
                    ))
            }
}

Looks like rustfmt fails to format the entire match expression because of the string literal that exceeds max width. @rgeorgiev583 To work around this for now, please make the string literal shorter manually or by setting wrap_str = true to rustfmt.toml (though the configuration option is kind of buggish).

@rgeorgiev583
Copy link
Author

@topecongiro
I split the string literal manually and rustfmt now seems to format everything correctly.
The workaround with wrap_str = true did not work for me, though (rustfmt seems to ignore that option as it is not present in rustfmt --help=config at all).
Anyway, thanks for the suggestion because it solved my issue!

@scampi
Copy link
Contributor

scampi commented Nov 22, 2018

@rgeorgiev583 there is also the option format_strings that would split the long string for you.

@scampi
Copy link
Contributor

scampi commented Nov 22, 2018

@topecongiro did you mean format_strings instead of wrap_str ?

ayazhafiz added a commit to ayazhafiz/rustfmt that referenced this issue Jun 8, 2020
Adds regression tests for the following issues which seem to be fixed on
master:

Closes rust-lang#1762
Closes rust-lang#2201
Closes rust-lang#2388
Closes rust-lang#2672
Closes rust-lang#2755
Closes rust-lang#2947
Closes rust-lang#2978
Closes rust-lang#3148
Closes rust-lang#3206

@topecongiro @calebcartwright appologies for the large number of issues
in this commit; if you prefer I can split it up into 2+.
ayazhafiz added a commit to ayazhafiz/rustfmt that referenced this issue Jun 9, 2020
Adds regression tests for the following issues which seem to be fixed on
master:

Closes rust-lang#1762
Closes rust-lang#2388
Closes rust-lang#2672
Closes rust-lang#2755
Closes rust-lang#2947
Closes rust-lang#2978
Closes rust-lang#3148
Closes rust-lang#3206

@topecongiro @calebcartwright appologies for the large number of issues
in this commit; if you prefer I can split it up into 2+.
calebcartwright pushed a commit that referenced this issue Jun 9, 2020
* Prune stale issues

Adds regression tests for the following issues which seem to be fixed on
master:

Closes #1762
Closes #2388
Closes #2672
Closes #2755
Closes #2947
Closes #2978
Closes #3148
Closes #3206

@topecongiro @calebcartwright appologies for the large number of issues
in this commit; if you prefer I can split it up into 2+.

* fixup! Prune stale issues
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants