Skip to content
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

silently fails to format match expression if arm pat contains comment #4119

Open
bradjc opened this issue Apr 13, 2020 · 7 comments
Open

silently fails to format match expression if arm pat contains comment #4119

bradjc opened this issue Apr 13, 2020 · 7 comments
Labels
a-comments a-matches match arms, patterns, blocks, etc bug Panic, non-idempotency, invalid code, etc. poor-formatting
Milestone

Comments

@bradjc
Copy link

bradjc commented Apr 13, 2020

For Tock, we run rustfmt with Travis CI, and some PRs (example1 and example2) are passing a rustfmt check while still using tabs for indentation.

  • No config options (we use defaults only).
  • Noticed this on nightly-2020-03-06 and nightly-2020-04-10.

I've also tried manually running rustfmt in the relevant crate on my computer and see the same effect. Based on a question on discord, I am opening this issue.

One example (src):

impl Driver for L3gd20Spi<'a> {
    fn command(&self, command_num: usize, data1: usize, data2: usize, _: AppId) -> ReturnCode {
        match command_num {
            0 /* check if present */ => ReturnCode::SUCCESS,
            // Check is sensor is correctly connected
            1 => {
				if self.status.get () == L3gd20Status::Idle {
					self.is_present ();
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}

			}
			// Power On
            2 => {
				if self.status.get () == L3gd20Status::Idle {
					self.power_on ();
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
			}
			// Set Scale
            3 => {
				if self.status.get () == L3gd20Status::Idle {
					let scale = data1 as u8;
					self.set_scale (scale);
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
            }
			// Enable High Pass Filter
            4 => {
				if self.status.get () == L3gd20Status::Idle {
					let mode = data1 as u8;
					let divider = data2 as u8;
					self.set_hpf_parameters (mode, divider);
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
			}
			// Set High Pass Filter Mode and Divider
            5 => {
				if self.status.get () == L3gd20Status::Idle {
					let enabled = if data1 == 1 { true } else { false };
					self.enable_hpf (enabled);
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
            }
			// Read XYZ
            6 => {
				if self.status.get () == L3gd20Status::Idle {
					self.read_xyz ();
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
			}
			// Read Temperature
            7 => {
				if self.status.get () == L3gd20Status::Idle {
					self.read_temperature ();
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
            }
            // default
            _ => ReturnCode::ENOSUPPORT,
        }
    }

    fn subscribe(
        &self,
        subscribe_num: usize,
        callback: Option<Callback>,
        _app_id: AppId,
    ) -> ReturnCode {
        match subscribe_num {
            0 /* set the one shot callback */ => {
				self.callback.insert (callback);
				ReturnCode::SUCCESS
			},
            // default
            _ => ReturnCode::ENOSUPPORT,
        }
    }
}

Another example (src):

impl Driver for Lsm303dlhcI2C<'a> {
    fn command(&self, command_num: usize, data1: usize, data2: usize, _: AppId) -> ReturnCode {
        match command_num {
            0 /* check if present */ => ReturnCode::SUCCESS,
            // Check is sensor is correctly connected
            1 => {
				if self.state.get () == State::Idle {
					self.is_present ();
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}

			}
			// Set Accelerometer Power Mode
            2 => {
				if self.state.get () == State::Idle {
                    if let Some (data_rate) = Lsm303dlhcAccelDataRate::from_usize (data1) {
                        self.set_power_mode(data_rate, if data2 != 0 { true } else { false });
                        ReturnCode::SUCCESS
                    }
                    else
                    {
                        ReturnCode::EINVAL
                    }
				}
				else
				{
					ReturnCode::EBUSY
				}
			}
			// Set Accelerometer Scale And Resolution
            3 => {
				if self.state.get () == State::Idle {
					if let Some (scale) = Lsm303dlhcScale::from_usize(data1) {
                        self.set_scale_and_resolution(scale, if data2 != 0 { true } else { false });
                        ReturnCode::SUCCESS
                    }
                    else
                    {
                        ReturnCode::EINVAL
                    }
				}
				else
				{
					ReturnCode::EBUSY
				}
            }
            // Set Magnetometer Temperature Enable and Data Rate 
            4 => {
				if self.state.get () == State::Idle {
                    if let Some (data_rate) = Lsm303dlhcMagnetoDataRate::from_usize (data2) {
                        self.set_temperature_and_magneto_data_rate (if data1 != 0 { true } else { false }, data_rate);
                        ReturnCode::SUCCESS
                    }
                    else
                    {
                        ReturnCode::EINVAL
                    }
				}
				else
				{
					ReturnCode::EBUSY
				}
			}
			// Set Magnetometer Range
            5 => {
				if self.state.get () == State::Idle {
					if let Some (range) = Lsm303dlhcRange::from_usize(data1) {
                        self.set_range(range);
                        ReturnCode::SUCCESS
                    }
                    else
                    {
                        ReturnCode::EINVAL
                    }
				}
				else
				{
					ReturnCode::EBUSY
				}
            }
			// Read Acceleration XYZ
            6 => {
				if self.state.get () == State::Idle {
					self.read_acceleration_xyz ();
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
            }
            // Read Temperature
            7 => {
				if self.state.get () == State::Idle {
					self.read_temperature ();
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
			}
			8 => {
				if self.state.get () == State::Idle {
					self.read_magnetometer_xyz ();
					ReturnCode::SUCCESS
				}
				else
				{
					ReturnCode::EBUSY
				}
            }
            // default
            _ => ReturnCode::ENOSUPPORT,
        }
    }

    fn subscribe(
        &self,
        subscribe_num: usize,
        callback: Option<Callback>,
        _app_id: AppId,
    ) -> ReturnCode {
        match subscribe_num {
            0 /* set the one shot callback */ => {
				self.callback.insert (callback);
				ReturnCode::SUCCESS
			},
            // default
            _ => ReturnCode::ENOSUPPORT,
        }
    }
}
@calebcartwright
Copy link
Member

Thanks for the report @bradjc. Looks like the problem is with the block comment in the match first match arm that's resulting in rustfmt failing to do any formatting within the match blocks (not just failing to convert the tabs).

This is definitely a bug, and as a temporary workaround you may want to consider changing those two block comments on the 0 arms to inline comments above the arms like was done for the others

bors bot added a commit to tock/tock that referenced this issue Apr 13, 2020
1755: capsules: remove block comment, rustfmt r=ppannuto a=bradjc

### Pull Request Overview

Remove a block comment to workaround a [bug](rust-lang/rustfmt#4119) in rustfmt.


### Testing Strategy

This pull request was tested by travis.


### TODO or Help Wanted

n/a


### Documentation Updated

- [x] Updated the relevant files in `/docs`, or no updates are required.

### Formatting

- [x] Ran `make formatall`.


Co-authored-by: Brad Campbell <[email protected]>
@calebcartwright calebcartwright added the bug Panic, non-idempotency, invalid code, etc. label Apr 14, 2020
@calebcartwright calebcartwright changed the title rustfmt not converting tabs to spaces with all default config options silently fails to format match expression if an arm contains a block comment Apr 14, 2020
@calebcartwright calebcartwright changed the title silently fails to format match expression if an arm contains a block comment silently fails to format match expression if arm pat contains block comment Apr 15, 2020
@topecongiro topecongiro added a-comments a-matches match arms, patterns, blocks, etc poor-formatting labels Jun 29, 2020
@topecongiro topecongiro modified the milestones: 2.1.0, 3.0.0 Jun 29, 2020
@Wilfred
Copy link

Wilfred commented Dec 8, 2020

I've been bitten by this too. This affects both the match bodies and the match patterns. The following code is unmodified by rustfmt, and no warnings are produced:

fn parse_term() {
    match x { |
       TokenKind::Name => {
                let qualified_name =1;
            }
            | TokenKind::Suspend
            // foo
            | _ => {}
        }
}

facebook-github-bot pushed a commit to facebook/hhvm that referenced this issue Dec 9, 2020
Summary:
Due to [rustfmt #4119](rust-lang/rustfmt#4119), comments inside pattern matches prevent formatting occurring.

Move the comments so rustfmt does the right thing.

Differential Revision: D25408396

fbshipit-source-id: eeab75cffd35b241640eaa22b24b0e42f3682501
@whizsid
Copy link
Contributor

whizsid commented Feb 21, 2021

I am working on this issue

@calebcartwright calebcartwright changed the title silently fails to format match expression if arm pat contains block comment silently fails to format match expression if arm pat contains comment Sep 8, 2021
bors bot added a commit to probe-rs/probe-rs that referenced this issue Sep 10, 2021
817: Clean up a lot of comments. r=Dirbaio a=Yatekii

- Add spaces after the // or ///.
- Add full stops.
- Also quote some variable names with backticks.
- Remove dead code.
- Move comments that were on the same line as actual code (I consider it bad style and it breaks rustfmt rust-lang/rustfmt#4119)

Co-authored-by: Noah Hüsser <[email protected]>
Co-authored-by: bors[bot] <26634292+bors[bot]@users.noreply.github.com>
mtoohey31 referenced this issue in mtoohey31/parsnips Nov 7, 2022
Bug report with rustfmt will follow when I find time for it.
readysetbot pushed a commit to readysettech/readyset that referenced this issue Nov 15, 2022
The presence of the comment in the middle of the pattern was triggering
rust-lang/rustfmt#4119, which meant that none
of the code in that match statement was being formatted by rustfmt. This
commit changes the existing code to avoid triggering that bug, and also
reformats the code in that block now that formatting is no longer
silently failing.

Change-Id: Idef7520a18a054f75adbab857823154c37fb270e
Reviewed-on: https://gerrit.readyset.name/c/readyset/+/3700
Tested-by: Buildkite CI
Reviewed-by: Griffin Smith <[email protected]>
@smmalis37
Copy link

I've just run into this, here's a very simple example:

fn main() {
    let i = 0;
    match i {
        0|1
        // Comment!
        |2|3 => {println!("<4");}
        _=>unreachable!(),
    }
}

Removing the comment allows rustfmt to work as expected, but so long as it's there the entire match block seems to be ignored for formatting, even the entirely unrelated _ arm. Is there any update on this case?

@daprilik
Copy link

On a semi-related note: are there any logging/tracing options that can be enabled to emit a warning in this and similar cases (where where rustfmt silently "gives up")?

@ytmimi
Copy link
Contributor

ytmimi commented Jan 23, 2023

@daprilik you can set error_on_unformatted = true.

Trying to format the code snippet from #4119 (comment) produces the following warning:

error[internal]: not formatted because a comment would be lost
 --> <stdin>:3
  |
3 |     match i {
  |
  = note: set `error_on_unformatted = false` to suppress the warning against comments or string literals

warning: rustfmt has failed to format. See previous 1 errors.

@not-holar
Copy link

not-holar commented Sep 29, 2023

Some simple examples of this

The following silently bails on the entire match statement

match (a) {
    0 // hello world
    | 1 => (),
    _ => (),
};

and so does this

match (a) {
    0 // hello world
    => (),
    _ => (),
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a-comments a-matches match arms, patterns, blocks, etc bug Panic, non-idempotency, invalid code, etc. poor-formatting
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants