I have an API that looks something roughly like this:
struct Foo {}
impl Foo {
pub fn create_key(&self) -> Key;
pub fn use_key(&self, key: &Key); // key MUST have been created by &self
}
struct Key {} // Contents elided in demo code
The Keys will only ever need to exist locally on the stack, ie
let key = foo.create_key();
// ... a couple more lines of code here
foo.use_key(key); // this call can happen multiple times
Is there a way to have the "key must be created by &self" constraint enforced by the type system? I currently do this using runtime checks that I can usually - but not always - persuade the compiler to remove, but it would be significantly neater if this were statically enforced.
This is sort of to do with ownership, so maybe there's a trick that can come out of framing it as "key must be owned by foo" or something like that?
I'm just reading through the GhostCell paper now, but it looks like it's along the right lines, thanks! I think "branded types" using lifetimes was the idea that I had in my head but didn't know how to realise. If they're as capable of a tool as they look, this is going to be a fun toy!
I'm still designing the details of my API, but branded types and invariant lifetimes as used in GhostCell have unlocked my design. Thanks @Cerber-Ursi.