#![feature(unboxed_closures)] #![feature(fn_traits)] #![feature(ptr_internals)] #![allow(dead_code)] #![allow(unused_imports)] #![allow(unused_variables)] use std::marker::PhantomData; use std::mem::transmute; use std::ops::{Deref, DerefMut}; struct Unique<'a, T: ?Sized> { v: *mut T, life: PhantomData<&'a T>, } unsafe impl Send for Unique<'_, T> {} unsafe impl Sync for Unique<'_, T> {} impl Unique<'_, T> { fn new(v: &mut T) -> Self { Unique { v, life: PhantomData } } fn get(&self) -> &T { self.deref() } fn get_mut(&mut self) -> &mut T { self.deref_mut() } } impl Deref for Unique<'_, T> { type Target = T; fn deref(&self) -> &Self::Target { unsafe { &*self.v } } } impl DerefMut for Unique<'_, T> { fn deref_mut(&mut self) -> &mut Self::Target { unsafe { &mut *self.v } } } #[test] fn unique_creation() { let mut x = 10; let y = &mut x; let u = Unique::new(y); assert_eq!(*u, 10); } #[test] fn unique_mutation() { let mut x = 10; let y = &mut x; let mut u = Unique::new(y); assert_eq!(*u, 10); *u = 100; assert_eq!(*u, 100); } #[allow(dead_code)] struct IBox<'a, T: ?Sized> { container: &'a mut [u8], ptr: Unique<'a, T>, } impl IBox<'_, T> { fn new(v: T, container: &mut [u8]) -> IBox { let ptr = unsafe { transmute(container.as_mut_ptr()) }; let mut unique = Unique::new(ptr); *unique = v; IBox { container, ptr: unique } } } impl IBox<'_, T> { fn move_out(self) -> T { *self } } #[test] fn ibox_new() { let container = &mut [0u8; 128]; IBox::new(10, container); } impl Deref for IBox<'_, T> { type Target = T; fn deref(&self) -> &Self::Target { self.ptr.get() } } impl DerefMut for IBox<'_, T> { fn deref_mut(&mut self) -> &mut Self::Target { self.ptr.get_mut() } } #[test] fn ibox_deref() { let container = &mut [0u8; 128]; let i = IBox::new(10, container); assert_eq!(*i, 10); } #[test] fn ibox_mutate() { let container = &mut [0u8; 128]; let mut i = IBox::new(10, container); assert_eq!(*i, 10); *i = 100; assert_eq!(*i, 100); } /* impl FnOnce for IBox<'_, F> where F: FnOnce + ?Sized { type Output = >::Output; extern "rust-call" fn call_once(self, args: Args) -> Self::Output { >::call_once(*self, args) } } */ impl + ?Sized> FnOnce for IBox<'_, F> { type Output = >::Output; extern "rust-call" fn call_once(self, args: A) -> Self::Output { >::call_once(self.move_out(), args) } } // impl FnMut for IBox<'_, F> // where // F: FnMut + ?Sized, // { // extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { // (**self).call_mut(args) // } // } // // impl Fn for IBox<'_, F> // where // F: Fn + ?Sized, // { // extern "rust-call" fn call(&self, args: Args) -> Self::Output { // (**self).call(args) // } // } fn closure(x: i32, container: &mut [u8]) -> IBox i32> { IBox::new(move |a| a + x, container) } #[test] fn iboxed_closure() { let mut container = [0u8; 128]; let closed_fn = closure(10, &mut container); assert_eq!(closed_fn(100), 110); }