Skip to content

Instantly share code, notes, and snippets.

@ClarkeRemy
Created July 27, 2024 10:11
Show Gist options
  • Save ClarkeRemy/b2eb208726c25eedb9a566f090ead28b to your computer and use it in GitHub Desktop.
Save ClarkeRemy/b2eb208726c25eedb9a566f090ead28b to your computer and use it in GitHub Desktop.
Rust with Holes
use std::marker::PhantomData;
pub fn main() {
let mut s = Splitter::new();
s.list[0] = 1;
s.id = 5;
println!("Splitter {{list : [{},{}], id : {} }}", s.list[0], s.list[1], s.id);
let (s, mut list) = s.mut_list();
let (s, mut id) = s.mut_id();
*id += 13;
list[1] = 25;
let s = s.unborrow_id(id);
let s = s.unborrow_list(list);
println!("Splitter {{list : [{},{}], id : {} }}", s.list[0], s.list[1], s.id);
}
type ID = usize;
type LIST = [u8;2];
struct Splitter<List = LIST, Id = ID> {list : List, id : Id}
impl Splitter{
fn new() -> Self {
Self { list: Default::default(), id: 0 }
}
}
impl<List,Id> Splitter<List,Id> {
fn mut_list(self)->(Splitter<(), Id>, Mutator<List, Splitter<(), Id>>) {
(Splitter {list : (), id : self.id}, Mutator{ mutable: self.list, src: PhantomData })
}
fn mut_id(self)->(Splitter<List, ()>, Mutator<Id, Splitter<List, ()>>) {
(Splitter {list : self.list, id : ()}, Mutator{ mutable: self.id, src: PhantomData })
}
}
impl<List> Splitter<List, ()> {
fn unborrow_id(self, id_mut : Mutator<ID, Self>) -> Splitter<List, ID> {
let id = unsafe{ id_mut.consume() };
Splitter { list: self.list, id }
}
}
impl<Id> Splitter<(), Id> {
fn unborrow_list(self, id_mut : Mutator<LIST, Self>) -> Splitter<LIST, Id> {
let list = unsafe{ id_mut.consume() };
Splitter { list, id: self.id }
}
}
#[must_use]
struct Mutator<M,Src> {
mutable : M,
src : PhantomData<Src>
}
impl<M,Src> Mutator<M,Src> {
unsafe fn consume(self) -> M {
let m = core::ptr::read(&self.mutable);
let _ = core::mem::ManuallyDrop::new(self);
m
}
}
impl<M,Src> Drop for Mutator<M,Src> {
fn drop(&mut self) {
core::panic!()
}
}
impl<M,Src> core::ops::Deref for Mutator<M,Src> {
type Target = M;
fn deref(&self) -> &Self::Target {
&self.mutable
}
}
impl<M,Src> core::ops::DerefMut for Mutator<M,Src> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.mutable
}
}
use std::marker::PhantomData;
pub fn main() {
let mut s = Splitter::new();
s.list[0]=1;
s.id = 5;
println!("Splitter {{list : [{},{}], id : {} }}", s.list[0], s.list[1], s.id);
let (s, mut list) = s.mut_list();
let (s, mut id) = s.mut_id();
*id += 13;
list[1]=25;
let s = s.unborrow_id(id);
let s = s.unborrow_list(list);
println!("Splitter {{list : [{},{}], id : {} }}", s.list[0], s.list[1], s.id);
}
type ID = usize;
type LIST = [u8;2];
#[derive(Debug)]
struct Z;
#[derive(Debug)]
struct S<T : Nat>(T);
mod sealed {
pub trait Nat { const VAL : Self; }
pub trait Succ : Nat { type S : Nat; }
pub trait Pred : Nat{ type P : Nat;}
}
use sealed::*;
impl Nat for Z { const VAL : Self = Z;}
impl<T : Nat> Nat for S<T>{ const VAL : Self = S(T::VAL); }
impl Succ for Z { type S = S<Z>; }
impl<T : Nat> Succ for S<T> { type S = S<Self>; }
impl<T : Nat> Pred for S<T> { type P = T; }
#[derive(Clone, Debug)]
struct Splitter<List = LIST, Id = ID, Scope : Nat = Z> {list : List, id : Id, _scope : Scope}
impl Splitter{
fn new() -> Self {
Self { list: [0;2], id: 0 , _scope : Z}
}
}
impl<List,Id,Scope : Succ> Splitter<List,Id, Scope> {
fn mut_list(self)->(Splitter<Scope::S, Id, Scope::S>, Mutator<List, Splitter<Scope::S, Id, Scope::S>>) {
( Splitter {list : Scope::S::VAL, id : self.id , _scope : Scope::S::VAL},
Mutator { mutable: self.list, src: PhantomData }
)
}
fn mut_id(self)->(Splitter<List, Scope::S, Scope::S>, Mutator<Id, Splitter<List, Scope::S, Scope::S>>) {
( Splitter {list : self.list, id : Scope::S::VAL, _scope : Scope::S::VAL},
Mutator{ mutable: self.id, src: PhantomData }
)
}
}
impl<List, Scope : Pred> Splitter<List, Scope, Scope> {
fn unborrow_id(self, id_mut : Mutator<ID, Self>) -> Splitter<List, ID, Scope::P> {
let id = unsafe{ id_mut.consume() };
Splitter { list: self.list, id , _scope: Scope::P::VAL}
}
}
impl<Id, Scope : Pred> Splitter<Scope, Id, Scope> {
fn unborrow_list(self, id_mut : Mutator<LIST, Self>) -> Splitter<LIST, Id, Scope::P> {
let list = unsafe{ id_mut.consume() };
Splitter { list, id: self.id, _scope : Scope::P::VAL }
}
}
#[must_use]
struct Mutator<M,Src> {
mutable : M,
src : PhantomData<Src>
}
impl<M,Src> Mutator<M,Src> {
unsafe fn consume(self) -> M {
let m = core::ptr::read(&self.mutable);
let _ = core::mem::ManuallyDrop::new(self);
m
}
}
impl<M,Src> Drop for Mutator<M,Src> {
fn drop(&mut self) {
core::panic!()
}
}
impl<M,Src> core::ops::Deref for Mutator<M,Src> {
type Target = M;
fn deref(&self) -> &Self::Target {
&self.mutable
}
}
impl<M,Src> core::ops::DerefMut for Mutator<M,Src> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.mutable
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment