but I don't know how to write the Cont::pinned function, or even if it's the right signature (if even possible).
The type parameter to Pin<P> is always a pointer or reference; a Pin never owns its data, except via an owning pointer type such as Box. Given that you want to keep the original value on the stack, the analogue of the function in the example is:
fn pinned(value: i32) -> Pin<&mut Self>;
But this isn't possible because a function can't return a reference to something it created - unless that something is stored on the heap or in static memory. So, if you were to construct a Pin of a stack-allocated value, you'd have to create the unpinned value first, so that that the pin can reference it.
Perhaps you might try to design an API that creates a Pin by mutating some data that is already on the stack:
let a: Option<Cont> = None;
let b: Option<Cont> = None;
let a = Cont::pinned(&mut a, 5);
let b = Cont::pinned(&mut b, 12);
But then the value would live longer than the pin and you can only enforce the pin guarantees while the pin is live, making this unsound.
To make it sound, you would need to somehow enforce that the original values cannot be accessed after the pin is dropped. This would result in a very constrained API. For example:
fn main() {
// setup_conts creates the pinned Cont values and calls the closure
setup_conts(5, 12, |a: Pin<&mut Cont>, b: Pin<&mut Cont>| {
// a and b can only be used inside this closure
})
}