I am trying to build a simple garbage collected VM in rust. Right now I am trying to figure out how to actually get memory to leak. Rust is so good a ownership I can't seem to get around it. In this example I am trying to make a hashmap of pointers to strings. anytime a string is updated I want to leak the old value (so that it wont break any code that has a reference to it) and put in the new value. Now anything that tries to access that string will get the new value and the old one can be garbage collected once no one is using it. This is what I have so far (I know it is a mess).
use std::collections::HashMap;
use std::pin::Pin;
fn main() {
let mut map: HashMap<u64, Pin<Box<Pin<Box<String>>>>> = HashMap::default();
map.insert(0, Box::pin(Box::pin("zero".to_owned())));
map.insert(1, Box::pin(Box::pin("one".to_owned())));
map.insert(2, Box::pin(Box::pin("two".to_owned())));
let mut boxed_value = map.get_mut(&0).unwrap().as_mut().get_mut(); // This addr should be constant
println!("box addr = {:p}", boxed_value);
let string_inside: *mut String = boxed_value.as_mut().get_mut();
println!("addr before = {:p}", string_inside);
println!("value before = {}", unsafe{&*string_inside});
// std::mem::forget(*boxed_value); // borrow checker won't let me move into forget
std::mem::replace(&mut *boxed_value, Box::pin("zilch".to_owned()));
println!("addr after = {:p}", string_inside);
println!("value after = {}", unsafe{&*string_inside});
}
The problem with this code is that drop
is being called on the old string "zero" (so the value after is garbage). Whenever I try and use Box::leak
or mem::forget
it tells me that it can't move into those functions. How can I force a leak in rust?