sapphicfettucine

software catgirl

kore signet-yang

trans, plural, philosophy student, bass player
excerpt «» developer «» digital archivist
wife to @ceolia <3


blog blog blog
blog.cat-girl.gay/

myrrlyn
@myrrlyn

would that be fucked up or what

so as you may or mayn't know, i am the author of the funty crate, which re-unifies all the primitives under a trait hierarchy so you can be generic over them, and i also experimentally am working on plugging pointer permissions into the type system with a module in bitvec.

incidentally this is what is colloquially known as "terminal library author brain", not as in "author of libraries for the terminal" but as in "incurable". if i ever learn haskel it is Over for you bitches

anyway

rust 1.65 has Generic Associated Types

which means i get to do incredibly brain genious shit like this:

trait Permission {
  type Raw<T: ?Sized>: Copy;
}

struct Shared; struct Unique;

impl Permission for Shared {
  type Raw<T: ?Sized> = *const T;
}
impl Permission for Unique {
  type Raw<T: ?Sized> = *mut T;
}
// this is a surprise tool that will help us later :)
impl Permission for (Shared, Unique) {
  type Raw<T: ?Sized> = <Shared as Permission>::Raw;
}

and not have to make Permission, or worse, Shared and Unique, generic over the type of the referent. cool, right? but wait. check this shit out:

trait Permission {
  // snip
  type Const: Permission;

  fn cast_const<T: ?Sized>(ptr: Self::Raw<T>) -> <Self::Const as Permission>::Raw<T>;
}

impl Permission for Shared {
  // snip

  type Const = Self;

  fn cast_const<T: ?Sized>(ptr: *const T) -> *const T { ptr }
}
impl Permission for for Unique {
  // snip

  type Const = (Shared, Self); // see? i told you

  fn cast_const<T: ?Sized>(ptr: *mut T) -> *const T { ptr.cast_const() }
}
impl Permission for (Shared, Unique) {
  // snip

  type Const = Self;

  fn cast_const<T: ?Sized>(ptr: *const T) -> *const T { ptr }
}

you may be thinking "alex what the fuck is this shit" which is fair. the fuck that this shit is, is that it's a type-system graph that allows you to at compile time prove that you can take a mutable pointer and dynamically degrade it to a const pointer and later re-upgrade it to mutable while completely disallowing upgrading const-only pointers to mutable. i'm not showing you a (Shared, Unique) -> Unique phase change because that's boring and you get the idea, but, yeah. if i don't define a (Shared) -> Unique phase change then you can never sneak mutability into a pointer that doesn't have it.

people keep telling me that the rust generic system is turing complete which means i am going to port miri to it

because i am fucking insane


You must log in to comment.

in reply to @myrrlyn's post:

this is absolutely wild and I love it.

i've kind of unironically considered similar things while working on a b-tree that supports compile-time parameterization to enable/disable copy-on-write capabilities (because with COW enabled but not used, there's still atomic refcount checks, etc.)

oh yeah did i mention i am also the author of radium, which plugs "access this location atomically, or don't" into the type system

i'm gonna unify Arc and Rc into Rc<R: Radium<usize>, T: ?Sized> next i'm just trying to postpose cracking open the standard library and working directly inside it for as long as possible

I think i saw one of your posts about radium on twitter - it looks pretty neat! If my b-tree was smaller in scope, i'd definitely consider it. there are currently some wild rust crimes being committed with my b-tree, but i'll have to talk about those in a dedicated post sometime

Turning Arc vs Rc into something to do with usize seems like it might be annoying from a pointer provenance / checking with miri point of view, but I don't really know (e.g. is miri ok with *const T -> usize -> *const T roundtrips yet?)

(also as an aside, the name "radium" for this is super cool)

the R: Radium<usize> bit is about the refcounters. Arc doesn't have atomic pointers in it at all. hhhowever, it turns out that pointer juggling in Rc is annoying to do outside of std for entirely different, non-provenance reasons, which is that "it's defined as Rc<T: ?Sized>"

hi lemme just fangirl a bit: bitvec is good, i've been using it heavily for WASM-4 junk in the last month, thank you, keep on spitting in god's eye with GATs

thanks! i'm glad people like it for Actual Programs And Stuff because god knows i'm probably never getting back to the point where i'll actually get to taste the fruits of my own labor lmao

people keep telling me that the rust generic system is turing complete which means i am going to port miri to it

I understood a quarter of what was said above this, but this... these words give me the warm fuzzies.

I'm looking forward to it! ^u^