SHARE
TWEET

Untitled

a guest Aug 25th, 2019 62 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #![feature(raw)]
  2. #![feature(untagged_unions)]
  3.  
  4. use std::mem;
  5. use std::ops::{Deref, DerefMut, Drop};
  6. use std::ptr;
  7. use std::raw::TraitObject;
  8.  
  9. fn main() {
  10.     let foo = Foo("les baguettes c'est merveilleux".to_owned());
  11.     let bar = Bar(vec![29, 87]);
  12.    
  13.     let a_just_do = ClosedJustDo::from(foo);
  14.     let another_just_do = ClosedJustDo::from(bar);
  15.    
  16.     a_just_do.just_do();
  17.     another_just_do.just_do();
  18. }
  19.  
  20. trait JustDo {
  21.     fn just_do(&self) {}
  22. }
  23.  
  24. struct Foo(String);
  25.  
  26. impl JustDo for Foo {
  27.     fn just_do(&self) {
  28.         println!("{}", self.0);
  29.     }
  30. }
  31.  
  32. struct Bar(Vec<u8>);
  33.  
  34. impl JustDo for Bar {
  35.     fn just_do(&self) {
  36.         println!("{:?}", self.0);
  37.     }
  38. }
  39.  
  40. struct ClosedJustDo {
  41.     vtable: *mut (),
  42.     drop: unsafe fn(*mut ()),
  43.     payload: ClosedJustDoPayload,
  44. }
  45.  
  46. #[allow(unions_with_drop_fields)]
  47. union ClosedJustDoPayload {
  48.     foo: Foo,
  49.     bar: Bar,
  50. }
  51.  
  52. impl From<Foo> for ClosedJustDo {
  53.     fn from(foo: Foo) -> Self {
  54.         let vtable = unsafe { mem::transmute::<&dyn JustDo, TraitObject>(&foo).vtable };
  55.         let drop = unsafe {
  56.             mem::transmute::<unsafe fn(*mut Foo), unsafe fn(*mut ())>(ptr::drop_in_place)
  57.         };
  58.         let payload = ClosedJustDoPayload { foo };
  59.         Self {
  60.             vtable,
  61.             drop,
  62.             payload,
  63.         }
  64.     }
  65. }
  66.  
  67. impl From<Bar> for ClosedJustDo {
  68.     fn from(bar: Bar) -> Self {
  69.         let vtable = unsafe { mem::transmute::<&dyn JustDo, TraitObject>(&bar).vtable };
  70.         let drop = unsafe {
  71.             mem::transmute::<unsafe fn(*mut Bar), unsafe fn(*mut ())>(ptr::drop_in_place)
  72.         };
  73.         let payload = ClosedJustDoPayload { bar };
  74.         Self {
  75.             vtable,
  76.             drop,
  77.             payload,
  78.         }
  79.     }
  80. }
  81.  
  82. impl Deref for ClosedJustDo {
  83.     type Target = dyn JustDo;
  84.    
  85.     fn deref(&self) -> &Self::Target {
  86.         unsafe {
  87.             let vtable = self.vtable;
  88.             let data = &self.payload as *const ClosedJustDoPayload as *mut ();
  89.             let object = TraitObject { vtable, data };
  90.             mem::transmute::<TraitObject, &Self::Target>(object)
  91.         }
  92.     }
  93. }
  94.  
  95. impl DerefMut for ClosedJustDo {
  96.     fn deref_mut(&mut self) -> &mut Self::Target {
  97.         unsafe {
  98.             let vtable = self.vtable;
  99.             let data = &mut self.payload as *mut ClosedJustDoPayload as *mut ();
  100.             let object = TraitObject { vtable, data };
  101.             mem::transmute::<TraitObject, &mut Self::Target>(object)
  102.         }
  103.     }
  104. }
  105.  
  106. impl Drop for ClosedJustDo {
  107.     fn drop(&mut self) {
  108.         unsafe {
  109.             (self.drop)(&mut self.payload as *mut ClosedJustDoPayload as *mut ());
  110.         }
  111.     }
  112. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top