Created
November 2, 2020 04:13
-
-
Save VigneshChennai/541b173f8c9402b4419b97321a7e42c9 to your computer and use it in GitHub Desktop.
Rust: Example of how "not owning a generic T" can allow unsound usage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(dropck_eyepatch)] | |
use std::alloc::Layout; | |
use std::ops::{Deref, DerefMut}; | |
// use std::marker::PhantomData; | |
struct InHeap<T: Sized> { | |
ptr: *const T, | |
//_m: PhantomData<T> // Using PhantomData will prevent "unsound usage" | |
} | |
impl<T> InHeap<T> { | |
fn new(v: T) -> Self { | |
let ptr = unsafe { std::alloc::alloc(Layout::new::<T>()) }; | |
if ptr.is_null() { | |
// abort on out of memory error | |
std::alloc::handle_alloc_error(Layout::new::<T>()); | |
} else { | |
unsafe { std::ptr::write(ptr as *mut T, v); } | |
InHeap { | |
ptr: ptr as *const T, | |
//_m: PhantomData | |
} | |
} | |
} | |
} | |
impl<T> Deref for InHeap<T> { | |
type Target = T; | |
fn deref(&self) -> &Self::Target { | |
unsafe { &*self.ptr } | |
} | |
} | |
impl<T> DerefMut for InHeap<T> { | |
fn deref_mut(&mut self) -> &mut Self::Target { | |
unsafe { &mut *(self.ptr as *mut T) } | |
} | |
} | |
unsafe impl<#[may_dangle] T> Drop for InHeap<T> { | |
fn drop(&mut self) { | |
unsafe { | |
std::ptr::drop_in_place(self.ptr as *mut T); | |
std::alloc::dealloc(self.ptr as *mut u8, Layout::new::<T>()) | |
}; | |
} | |
} | |
#[derive(Debug)] | |
struct MyString<'a>(&'a String); | |
impl<'a> Drop for MyString<'a> { | |
fn drop(&mut self) { | |
println!("Accessing '{}' in MyString's Drop", self.0) | |
} | |
} | |
fn main() { | |
let mut foo = InHeap::new(None); | |
let mut bar = String::from("Hello everyone!"); | |
*foo = Some(MyString(&mut bar)); | |
drop(bar); | |
println!("The variable bar='Hello everyone!' is drop. \ | |
Any further access to the value is UB" | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment