Guest User

Untitled

a guest
Aug 25th, 2019
65
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