rust-lang / rust-lang/rustfmt

silently fails to format match expression if arm pat contains comment

Open
#4,119 9 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-comments A-matches C-bug I-poor-formatting
Dominant language
Rust
Stars
7k
Forks
1.1k
Avg merge
2d 13h
Merged PRs (30d)
24

Description

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,
        }
    }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the failure with the Rust match-expression examples from the issue, including comments in arm patterns, using rustfmt's default configuration and the referenced nightly versions. Trace the formatting path for match arms and verify that the affected input is reformatted and no longer silently leaves tab indentation.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.