Skip to content

Don't emit no-op &T → &T reborrows - #164014

Open
Jules-Bertholet wants to merge 2 commits into
rust-lang:mainfrom
Jules-Bertholet:no-noop-reborrows
Open

Jules-Bertholet wants to merge 2 commits into
rust-lang:mainfrom
Jules-Bertholet:no-noop-reborrows

Conversation

@Jules-Bertholet

@Jules-Bertholet Jules-Bertholet commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

View all comments

Except inside closures, where we need to keep capture inference stable. Gets rid of MIR bloat, and improves diagnostics.

See also #163717 (would allow doing this even inside closures), #163494 (would allow doing this for mutable references outside closures).

r? compiler

@rustbot label A-coercions

@rustbot

rustbot commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

clippy is developed in its own repository. If possible, consider making this change to rust-lang/rust-clippy instead.

cc @rust-lang/clippy

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 9, 2026
@rustbot rustbot added the A-coercions Area: implicit and explicit `expr as Type` coercions label Oct 9, 2026
where
T: TrivialClone,
{
#[inline]

@Jules-Bertholet Jules-Bertholet Oct 9, 2026 •

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.

To make tests/codegen-llvm/lib-optimizations/append-elements.rs happy. That test is really fragile…

View changes since the review

@jieyouxu

jieyouxu commented Oct 9, 2026

Copy link
Copy Markdown
Member

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 9, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Oct 9, 2026
Don't emit no-op `&T` → `&T` reborrows
@rust-bors

rust-bors Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: d77c4b4 (d77c4b4f551a87fc763f35c94b4177493a25ab83)
Base parent: 0f6e5bf (0f6e5bf4c63a0ab336cc62de446b77123effaffc)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (d77c4b4): comparison URL.

Overall result: ✅ improvements - no action needed

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

@bors rollup=never rustc-perf
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.2% [0.2%, 0.2%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.7% [-3.9%, -0.1%] 175
Improvements ✅
(secondary)
-1.2% [-7.0%, -0.1%] 151
All ❌✅ (primary) -0.7% [-3.9%, 0.2%] 176

Max RSS (memory usage)

Results (primary -2.1%, secondary -2.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.1% [2.1%, 4.2%] 2
Improvements ✅
(primary)
-2.1% [-6.2%, -0.8%] 16
Improvements ✅
(secondary)
-3.7% [-6.7%, -0.7%] 16
All ❌✅ (primary) -2.1% [-6.2%, -0.8%] 16

Cycles

Results (primary -2.7%, secondary -4.6%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
7.1% [7.1%, 7.1%] 1
Improvements ✅
(primary)
-2.7% [-3.1%, -2.2%] 5
Improvements ✅
(secondary)
-5.4% [-8.9%, -1.8%] 15
All ❌✅ (primary) -2.7% [-3.1%, -2.2%] 5

Binary size

Results (primary 0.1%, secondary -0.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.3% [0.1%, 1.1%] 27
Regressions ❌
(secondary)
0.2% [0.2%, 0.2%] 1
Improvements ✅
(primary)
-0.3% [-1.0%, -0.0%] 22
Improvements ✅
(secondary)
-0.2% [-0.5%, -0.1%] 12
All ❌✅ (primary) 0.1% [-1.0%, 1.1%] 49

Bootstrap: 486.533s -> 486.402s (-0.03%)
Artifact size: 406.44 MiB -> 406.63 MiB (0.05%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 9, 2026
@theemathas

Copy link
Copy Markdown
Contributor

Does this have implications on what Miri can catch?

@Jules-Bertholet

Copy link
Copy Markdown
Contributor Author

Does this have implications on what Miri can catch?

It shouldn't. Miri does retags on every typed copy.

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rustbot

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rustbot

This comment has been minimized.

@adwinwhite adwinwhite left a comment •

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.

I think the intention of this PR is to skip more no-op reborrows?
Some explanation on what the "more" part is would be awesome.
As someone who's not super familiar with coercions, this isn't too obvious :>

View changes since this review

Comment thread compiler/rustc_hir_typeck/src/coercion.rs Outdated
Comment thread compiler/rustc_hir_typeck/src/coercion.rs Outdated
Comment thread compiler/rustc_hir_typeck/src/coercion.rs Outdated
@theemathas

This comment has been minimized.

@adwinwhite adwinwhite left a comment •

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.

This change looks very good to me. But I'm not totally confident about its implication for borrowck. Could we accidentally allow some unsound code to compile now that we have less lifetime shortening? Hope someone more experienced with borrowck can confirm it's okay. cc @BoxyUwU @lcnr

View changes since this review

Comment on lines +252 to +263
Adjust::Borrow(AutoBorrow::Ref(m)) => {
// Don't emit no-op &T -> &T reborrows
if let AutoBorrowMutability::Not = m
&& let ExprKind::Deref { arg: derefed_expr } = expr.kind
&& let ty::Ref(_, _, ty::Mutability::Not) =
self.thir.exprs[derefed_expr].ty.kind()
// FIXME: removing these reborrows may prevent closure upvars from resolving
&& !self.tcx.is_closure_like(self.body_owner)
{
assert_eq!(self.thir.exprs.last_index(), Some(derefed_expr));
return self.thir.exprs.pop().unwrap();
} else {

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.

This covers the skipping in coercion, right? It's more general, since it removes all redundant adjustments, whereas the coercion skipping only removes one autoborrow + deref pair?
It also skips adjustments from method confirmation 🤔

vibe: how about we only keep this skipping in THIR building and drop those in coercion?
This shouldn't affect the major perf win in borrowck, and it reduces duplicated logic for this optimization.

@Jules-Bertholet Jules-Bertholet Oct 19, 2026 •

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.

Not doing HIR skipping might lose some of the Clippy and diagnostics improvements. I will check

@Jules-Bertholet Jules-Bertholet Oct 19, 2026 •

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.

Can confirm, we lose the Clippy wins. Which is quite minor in this PR, but a bigger loss with #163717 (lose all the redundant_closure improvements)

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.

Could you link some examples? I didn't find tests mentioning redundant_closure or redundant_clone in #163717. Only found one redundant_closure_for_method_call.

Curious about why not doing HIR skipping affects them.

@Jules-Bertholet Jules-Bertholet Oct 21, 2026 •

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.

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.

These lints look at a closure's HIR to determine "does it do anything other than a function call", and coercion counts as "anything"

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rustbot

This comment has been minimized.

@Jules-Bertholet

Jules-Bertholet commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

I just realized—this does have an effect on borrowcheck. The following goes from compile fail → pass:

fn main() {
    let x: &'static ();
    let _: &_ = /* there used to be an implicit reborrow here */ x;
}

Personally, I think we should accept this, but worth discussing.

Note that the following compiles today:

fn main() {
    let x: &'static ();
    let _ = x;
}

Zulip thread

What semantics do we want here? @rustbot label I-opsem-nominated T-opsem T-types

@rust-bors

This comment has been minimized.

@rustbot rustbot added the I-opsem-nominated Nominated for discussion by the opsem team label Oct 21, 2026
Except inside closures, where we need to keep capture inference stable.
Gets rid of MIR bloat, and improves diagnostics.
@rustbot

rustbot commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

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.

@rustbot rustbot added T-opsem Relevant to the opsem team T-types Relevant to the types team, which will review and decide on the PR/issue. labels Oct 21, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-coercions Area: implicit and explicit `expr as Type` coercions I-opsem-nominated Nominated for discussion by the opsem team S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-opsem Relevant to the opsem team T-types Relevant to the types team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants