-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow moving out of &'static mut T
#125868
Comments
Miri also doesn't complain about this program, one which is surely not what you intend: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=4a15c73887bce9565554ebf5b12e3627 |
@Ddystopia your To write the demo you want, you must use custom MIR: https://doc.rust-lang.org/nightly/std/intrinsics/mir/index.html |
Original(?) discussion started here. |
In any case, I think the basic reasoning here is wrong: The If the following entirely safe code were to be allowed to compile, we would have access to a moved-from value: #[derive(Debug)]
struct NotCopy(u8);
fn main() {
let x: &'static mut NotCopy = Box::leak(Box::new(NotCopy(0u8)));
let y: &'static mut NotCopy = &mut *x;
let z = *y;
println!("{:?}", *x); // oops, use of moved-from value
} |
The reborrow used to create There's more discussion in this RFC thread. I personally don't feel there are strong enough upsides for language support, e.g. fn take<T: Send>(reference: &'static mut T) -> T {
let (sender, receiver) = std::sync::mpsc::channel();
std::thread::spawn(move || {
replace_with::replace_with_or_abort(reference, |t| {
let _ = sender.send(t);
loop {}
})
});
receiver.recv().unwrap()
}
let foo: &'static mut NotDefaultNotCopy = Box::leak(Box::new(NotDefaultNotCopy([1; 20])));
let reborrowed_even = &mut *foo;
let foo_taken = take(reborrowed_even);
println!("{:?}", foo_taken.0);
// Trying to use `foo` is an error because `*foo` is exclusively reborrowed forever |
Thanks for the correction! |
I do agree that there might not be urging need for this, but it sometimes might be useful during embedded development and if something will change with borrow checker's attitude to moving out of mutable references, then it might not take a lot of extra work to consider adding this feature, which will not break anything and apparently sound. |
There was a potentially breaking use case in the RFC thread, depending on how the decision goes. As far as I know there hasn't been an FCP on the topic. That said, opinions did seem favorable on the side of this being sound. That RFC was closed in part due to concerns about adding an API that aborts. I will note that a proposal to add a function like Blessing this operation means that every |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Thank you for note! Here is another example, which is closer to what I wanted to demonstrate playground I also tried custom MIR, but compiler kept ICE-ing and I gave up |
I agree that this is sound: fn take<T>(reference: &'static mut T) -> T {
unsafe { core::ptr::read(reference) }
} It would be fairly easy to prove this in Rustbelt as well. Not sure if it's worth having special support for this in the borrow checker, a dedicated method seems more clear / less magic to me. |
Hello, it is perfectly sound to move out of
&'static mut T
and have that reference consumed, as no safe code can accessT
under the reference after that point.For example, miri is happy with that code if
take
in unsafely written (but detects leak) playgroundHere is code with more unsafe but with no miri leak warnings: playground
The text was updated successfully, but these errors were encountered: