Skip to content

Prevent ranges from getting collapsed in patterns#6871

Open
ytmimi wants to merge 7 commits intorust-lang:mainfrom
ytmimi:issue_6869
Open

Prevent ranges from getting collapsed in patterns#6871
ytmimi wants to merge 7 commits intorust-lang:mainfrom
ytmimi:issue_6869

Conversation

@ytmimi
Copy link
Copy Markdown
Contributor

@ytmimi ytmimi commented Apr 17, 2026

Fixes #6869

Expression rewriting handled this correctly, but there was distinct logic implemented for patterns. I've extracted the range formatting logic used by expressions into a common rewrite_range function and reused that when rewriting ranges in patterns and types. Was able to remove a nice amount of code after these changes were done.

PR is broken up into logical commits. Feel free to review the PR as a whole or commit by commit.

@rustbot rustbot added the S-waiting-on-review Status: awaiting review from the assignee but also interested parties. label Apr 17, 2026
@ytmimi
Copy link
Copy Markdown
Contributor Author

ytmimi commented Apr 17, 2026

Just to be sure these changes wouldn't impact things I ran the Diff-Check --edition=2021 --style-edition=2021. Things seem to be working as expected.

Copy link
Copy Markdown
Contributor

@matthewhughes934 matthewhughes934 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/types.rs Outdated
Comment on lines +1073 to +1074
lhs.as_deref().map(|x| &(*x.value)),
rhs.as_deref().map(|x| &(*x.value)),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

discussion/question: I'm still learning my way around Rust, is there generally a preference for the symbolic/explicit (*&) approach vs. things like Box<T, A>.as_ref?

Suggested change
lhs.as_deref().map(|x| &(*x.value)),
rhs.as_deref().map(|x| &(*x.value)),
lhs.as_deref().map(|x| x.value.as_ref()),
rhs.as_deref().map(|x| x.value.as_ref()),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&(*x) makes it explicit that you're taking a reference to an object after dereferencing a pointer. No real preference for me so I'll update this to use as_ref. Thanks for flagging.

Comment thread src/range.rs Outdated
Comment on lines +44 to +77
match (lhs.as_ref().map(|x| &**x), rhs.as_ref().map(|x| &**x)) {
(Some(lhs), Some(rhs)) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!(" {delim} ")
} else {
default_sp_delim(Some(lhs), Some(rhs))
};
rewrite_pair(
&*lhs,
&*rhs,
PairParts::infix(&sp_delim),
context,
shape,
context.config.binop_separator(),
)
}
(None, Some(rhs)) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!("{delim} ")
} else {
default_sp_delim(None, Some(rhs))
};
rewrite_unary_prefix(context, &sp_delim, &*rhs, shape)
}
(Some(lhs), None) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!(" {delim}")
} else {
default_sp_delim(Some(lhs), None)
};
rewrite_unary_suffix(context, &sp_delim, &*lhs, shape)
}
(None, None) => Ok(delim.to_owned()),
}
Copy link
Copy Markdown
Contributor

@matthewhughes934 matthewhughes934 Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for a followup, since this is all moved code, but I think the ref/de-refer-ing in this block could be simplified

Suggested change
match (lhs.as_ref().map(|x| &**x), rhs.as_ref().map(|x| &**x)) {
(Some(lhs), Some(rhs)) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!(" {delim} ")
} else {
default_sp_delim(Some(lhs), Some(rhs))
};
rewrite_pair(
&*lhs,
&*rhs,
PairParts::infix(&sp_delim),
context,
shape,
context.config.binop_separator(),
)
}
(None, Some(rhs)) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!("{delim} ")
} else {
default_sp_delim(None, Some(rhs))
};
rewrite_unary_prefix(context, &sp_delim, &*rhs, shape)
}
(Some(lhs), None) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!(" {delim}")
} else {
default_sp_delim(Some(lhs), None)
};
rewrite_unary_suffix(context, &sp_delim, &*lhs, shape)
}
(None, None) => Ok(delim.to_owned()),
}
match (lhs, rhs) {
(Some(lhs), Some(rhs)) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!(" {delim} ")
} else {
default_sp_delim(Some(lhs), Some(rhs))
};
rewrite_pair(
lhs,
rhs,
PairParts::infix(&sp_delim),
context,
shape,
context.config.binop_separator(),
)
}
(None, Some(rhs)) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!("{delim} ")
} else {
default_sp_delim(None, Some(&rhs))
};
rewrite_unary_prefix(context, &sp_delim, rhs, shape)
}
(Some(lhs), None) => {
let sp_delim = if context.config.spaces_around_ranges() {
format!(" {delim}")
} else {
default_sp_delim(Some(&lhs), None)
};
rewrite_unary_suffix(context, &sp_delim, lhs, shape)
}
(None, None) => Ok(delim.to_owned()),
}

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. The lhs and the rhs are Option<&ast::Expr> so we can definitely simplify this. We actually don't need to specify any & or explicitly deference anything. I'll add a commit

ytmimi added 7 commits April 21, 2026 16:01
Move the range rewrite logic from `src/exrp.rs` to `src/range.rs`. There are a
few different places where we rewrite ranges so centralizing the logic in a
single location is ideal.
Cleans up the syntax a little. Was suggested in the PR review.
Reuse the range rewrite logic that we abstracted into `src/range.rs`.
Reuse the range rewrite logic that we abstracted into `src/range.rs`.
Now that we've centralized the logic into `rewrite_range` we no longer need a
dedicated `rewrite_range_pat` function. Getting rid of that also lets us remove
some other unnecessary code which is nice.
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 21, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@jieyouxu jieyouxu self-assigned this Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Formatting float ranges may result in invalid code

4 participants