Preserve generic reborrow while fixing identity moves#156786
Conversation
Ordinary identity move/coercion contexts should not become Adjust::GenericReborrow merely because the target ADT implements Reborrow. Try ordinary unification first in the ordinary identity-move path, while preserving intended generic Reborrow behavior for implicit argument reborrows. This keeps custom Reborrow tests such as repeated by-value use of marker and mutable wrapper types working as before. The fix is intentionally limited to typeck ordering and does not redesign the Reborrow representation.
|
r? @jieyouxu rustbot has assigned @jieyouxu. Use Why was this reviewer chosen?The reviewer was selected based on:
|
There was a problem hiding this comment.
I don't think this should be necessary, and I believe this would not match the semantics that we expect from comparing to &mut _.
If you dump the MIR for an identity function that takes a &mut _ you should see that it performs two reborrows, one from argument to local and one from local to return value. I assume with this change an identity function of a Reborrow type would no longer show the same form but would instead just have a single move. If one day &mut _ unifies with Reborrow then that could cause issues.
Further, I think this change would not actually fix the general issue. eg. I expect this function would not work:
fn foo<'a>(x: CustomMut<'a>) -> Result<(), CustomMut<'a>> {
bar(x)?; // <--
println!("{x:?}");
Ok(())
}
// this function would work
fn bar<'a>(x: CustomMut<'a>) -> Result<(), CustomMut<'a>> {
Err(x)
}I expect that the marked line with ? usage would not compile as a reborrow will happen there, capturing the local x and then making the borrow checker angry at us trying to return a local value.
We have talks ongoing at the Rust all-hands to correct the implementation / design to resolve the problem of borrowing local places in reborrowing generally.
Thanks, I think you are right that this PR is treating a symptom at the wrong layer. I checked the ordering change again. The PR makes That differs from the pub fn id_mut<'a, T>(x: &'a mut T) -> &'a mut T { x }with I also tested the I will be closing this PR, please let me know what happens at All Hands. |
Fixes a move-vs-generic-reborrow selection issue in typeck without changing the intended generic
Reborrowbehaviour.In ordinary identity move/coercion contexts, a
T -> Tuse should not becomeAdjust::GenericReborrowmerely because the target ADT implementsReborrow. This PR makes those ordinary identity contexts try normal unification first; if normal unification succeeds, the expression remains an ordinary move/copy.cc @aapoalas