rust-lang / rust-lang/rustfmt

Improve formatting of pattern alternatives

Open
#4,005 6 comments 7 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-matches
Dominant language
Rust
Stars
7k
Forks
1.1k
Avg merge
2d 13h
Merged PRs (30d)
24

Description

I found no mention in the spec of how to format pattern alternatives like A | B | C => expr, so I have to assume that what rustfmt does there is some ad-hoc decision made during implementation. I think that formatting should be given some thought. I am not sure where to start with that, so I figured I'd open an issue. ;)

Some of the problems that we currently have:

  • With long lists of patterns (that do not fit on a single line), we end up with code like this:
Pat1
| Pat2
| Pat3
| Pat4 => ...

Notice how the patterns start at different vertical positions, destroying symmetry. This is unlike how every other "list-like thing" is formatted, which all are properly vertically aligned. Also see https://github.com/rust-lang/rustfmt/issues/3973.

  • With long matches, rustfmt can end up generating code like this:
        match ty.kind {
            // Types without identity.
            ty::Bool
            | ty::Char
            | ty::Int(_)
            | ty::Uint(_)
            | ty::Float(_)
            | ty::Str
            | ty::Array(_, _)
            | ty::Slice(_)
            | ty::RawPtr(_)
            | ty::Ref(_, _, _)
            | ty::FnPtr(_)
            | ty::Never
            | ty::Tuple(_)
            | ty::Dynamic(_, _) => self.pretty_print_type(ty),

            // Placeholders (all printed as `_` to uniformize them).
            ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error => {
                write!(self, "_")?;
                Ok(self)
            }

Notice how the two lists of alternatives are formatted very differently. This should be done in a more consistent way. Just like https://github.com/rust-lang/rustfmt/issues/3995 is about formatting the match arms themselves consistent across a match, I think rustfmt should also format lists of pattern alternatives consistent across a match.

Things get even more complicated when considering match guards... but one step after the other, I'd say. ;)

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 reviewing the issue's examples of multiline pattern alternatives and the related issues 3973 and 3995. The payload names no files, tests, or entry points, so locating the formatter logic and agreeing on the desired formatting rules would be the first step. Done means pattern alternatives are formatted consistently, including across match arms, with match guards considered as scope allows.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.