Description
Given the code:
#![allow(unused_mut)]
use core::mem::ManuallyDrop;
pub struct RefWrapper<'a, T: ?Sized> {
slot: &'a mut T,
}
impl<'a, T: ?Sized> RefWrapper<'a, T> {
pub fn into_raw(this: Self) -> *mut T {
let mut this = ManuallyDrop::new(this);
// let this = &mut *this;
this.slot as *mut T
}
}
The current output is:
error[E0596]: cannot borrow data in a dereference of `ManuallyDrop<RefWrapper<'_, T>>` as mutable
--> src/lib.rs:13:9
|
13 | this.slot as *mut T
| ^^^^^^^^^ cannot borrow as mutable
|
= help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `ManuallyDrop<RefWrapper<'_, T>>`
Ideally, this should just work1. Uncommenting the commented line to add an explicit mutable reborrow allows the code to work as intended. But even if it can't work, the error is clearly very unhelpful, as the issue isn't the lack of DerefMut
, but that the compiler selected a shared Deref
evaluation of the place.
@rustbot modify labels +C-bug +D-incorrect
Footnotes
-
Importantly, just work and produce a pointer with valid
mut
provenance. It would be technically correct but misleading to allow&mut T as *mut T
behind a shared reference to behave like&mut T as *const T as *mut T
. The actually useful behavior is for the fact thatas *mut
is a by-mut
use of thethis.slot
place to flow back into the selection of whether to evaluate thethis.slot
place by-ref (viaDeref
) or by-mut (viaDerefMut
) the same way other by-mut
place usage does. ↩