Skip to content

Conversation

@aapoalas
Copy link
Contributor

@aapoalas aapoalas commented Jan 27, 2026

With this PR we now have basic functional Reborrow and CoerceShared traits. The current limitations are:

  1. Reborrowable types can only have one lifetime parameter, so as to avoid having to figure out and store in rmeta the information of which lifetimes weaken during reborrowing.
  2. Reborrowing of &mut wrappers is working (though I've not tested generic wrappers like Option<&mut T> yet), but CoerceShared of &mut wrappers currently causes an ICE.

The remaining tasks to complete before I'd consider this PR mergeable are:

  • Fix ICE on CoerceShared. Unfortunately this might require dipping into rmeta.
  • Expand the tests to give a more complete view of the current state of the experiment.

Reborrow traits experiment: #145612

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. 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 Jan 27, 2026
@rust-log-analyzer

This comment has been minimized.

@aapoalas aapoalas force-pushed the aapoalas/reborrow-and-coerce-shared-first-version branch from e4c08f7 to 3b1957a Compare January 27, 2026 17:03
@rust-log-analyzer

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.

@aapoalas aapoalas marked this pull request as ready for review February 2, 2026 21:16
@rustbot
Copy link
Collaborator

rustbot commented Feb 2, 2026

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred in match checking

cc @Nadrieril

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a, @makai410

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred to constck

cc @fee1-dead

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 2, 2026
@aapoalas
Copy link
Contributor Author

aapoalas commented Feb 2, 2026

r? compiler

@rustbot rustbot assigned jackh726 and unassigned tmandry Feb 2, 2026
/// Wraps a value in an unsafe binder.
WrapUnsafeBinder(Operand<'tcx>, Ty<'tcx>),

/// A reborrowable type being reborrowed
Copy link
Member

Choose a reason for hiding this comment

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

Please explain the runtime behavior of this operation.

The interpreter implementation seems to indicate that this is equivalent to a normal assignment of Copy($place). Why is it even a separate statement?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, my apologies, I definitely should've added more information around this: I added a link to the experiment tracking issue into the opening comment which contains some more information and links but basically: in the trivial case (#[repr(transparent)]-compatible memory layout of types and a single lifetime) Reborrow is a Copy plus extra borrow checking analysis to perform the same reborrowing operation as happens with &'a mut T, but now on some user-defined ADT struct Custom<'a>(..). CoerceShared is then the &'a mut T -> &'a T equivalent of this operation and thus also requires a user-defined target type.

This PR does not implement any non-trivial cases so in both cases the runtime effect is exactly equivalent to a Copy, but future expansions should make CoerceShared possible even if the layouts of the source and target types do not match, including the possibility for the target type to drop out some fields from the source type. (This has a requested use-case where a custom exclusive reference type has some write-time metadata which is then not necessary in a read-only reference.)

Copy link
Member

Choose a reason for hiding this comment

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

I added a link to the experiment tracking issue

That link is broken btw.

future expansions should make CoerceShared possible even if the layouts of the source and target types do not match, including the possibility for the target type to drop out some fields from the source type.

That sounds like an operation that is too complicated to be a single MIR statement, it should instead be encoded as a sequence of simpler operations. Otherwise every MIR consumer has to re-implement all that logic, partially defeating the point of having an IR like MIR in the first place.

}

adjustment::Adjust::GenericReborrow(_reborrow) => {
// Do the magic!
Copy link
Contributor

@dingxiangfei2009 dingxiangfei2009 Feb 3, 2026

Choose a reason for hiding this comment

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

Oh we should call delegates. See the ReborrowPin arm and that is basically what we want to do.

And eventually we should be able to subsume ReborrowPin case hopefully.

// `&mut T: DerefMut` tho, so it's kinda moot.
}
Adjust::GenericReborrow(_) => {
// No effects to enforce here.
Copy link
Contributor

@dingxiangfei2009 dingxiangfei2009 Feb 3, 2026

Choose a reason for hiding this comment

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

We should do something here. The type would change after a generic reborrow, ie the CoerceShared case.

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 3, 2026

Where can I read context on what CoerceShared is/why it exists, and what the design for reborrow traits is

block.and(PlaceBuilder::from(temp))
}
ExprKind::Reborrow { source: _, mutability: _, ty: _ } => {
todo!();
Copy link
Contributor

Choose a reason for hiding this comment

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

We should generate a temporary. Therefore, we can merge this case one above, in other words build a temporary place, so that the reborrowing receives its own region "token."

@aapoalas
Copy link
Contributor Author

aapoalas commented Feb 3, 2026

Where can I read context on what CoerceShared is/why it exists, and what the design for reborrow traits is

I added a link to the experiment tracking issue but put it very shortly: Reborrow is to struct X<'a>(..) what &mut *x is for &mut T, and CoerceShared is the equivalent operation as &*x. CoerceShared takes a type argument instead of having an associated type in expectation of it being possible to reborrow types like struct Double(&mut A, &mut B) which would then have three different "shared reference" variants: struct DR1(&A, &mut B), struct DR2(&mut A, &B), and struct DR3(&A, &B), though I am currently doubting the wisdom of this choice and it may return to using an associated type.

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 3, 2026

I think I'll just
r? me
on this since I know jack is quite busy with coercions work right now and this should probably have a types reviewer 🤔

@rustbot rustbot assigned BoxyUwU and unassigned jackh726 Feb 3, 2026
@aapoalas
Copy link
Contributor Author

aapoalas commented Feb 3, 2026

I think I'll just r? me on this since I know jack is quite busy with coercions work right now and this should probably have a types reviewer 🤔

Thank you <3 my top secret plan (designed together with tmandry) was to get a compiler review and then reroll into types to that view as well so that works well :)

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. 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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants