-
Notifications
You must be signed in to change notification settings - Fork 14k
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
mutprovenance. It would be technically correct but misleading to allow&mut T as *mut Tbehind a shared reference to behave like&mut T as *const T as *mut T. The actually useful behavior is for the fact thatas *mutis a by-mutuse of thethis.slotplace to flow back into the selection of whether to evaluate thethis.slotplace by-ref (viaDeref) or by-mut (viaDerefMut) the same way other by-mutplace usage does. ↩