Skip to content

Instantly share code, notes, and snippets.

@nixpulvis
Created March 3, 2026 12:36
Show Gist options
  • Select an option

  • Save nixpulvis/6016e43deb7dec7251810b71b077fd57 to your computer and use it in GitHub Desktop.

Select an option

Save nixpulvis/6016e43deb7dec7251810b71b077fd57 to your computer and use it in GitHub Desktop.
use std::marker::PhantomPinned;
use std::ops::Deref;
use std::pin::{Pin, pin};
struct NoMove(i32, PhantomPinned);
impl Deref for NoMove {
type Target = i32;
fn deref(&self) -> &Self::Target {
&self.0
}
}
struct DummyPtr(NoMove);
impl Deref for DummyPtr {
type Target = NoMove;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
// Can't do it.
// Pin::new(DummyPtr(NoMove(1, PhantomPinned)));
// This works.
unsafe { Pin::new_unchecked(DummyPtr(NoMove(1, PhantomPinned))) };
// Let's try to make a pin...
let a = Pin::new(NoMove(1, PhantomPinned));
println!("a: {:p}", &*a);
let b = a;
println!("b: {:p}", &*b);
// It compiled, but moved!
// This is because: (NoMove(...) as Deref)::Target is i32: Unpin.
// Not meaningfully different.
let c = unsafe { Pin::new_unchecked(NoMove(1, PhantomPinned)) };
println!("c: {:p}", &*c);
let d = c;
println!("d: {:p}", &*d);
// Now we create a reference to `pinned`, and pin that.
let mut pinned = NoMove(1, PhantomPinned);
let e = unsafe { Pin::new_unchecked(&mut pinned) };
println!("e: {:p}", &*e);
let f = e;
println!("f: {:p}", &*f);
// It works because: (&mut pinned as Deref)::Target is NoMove: !Unpin
// `pin!` is just a macro that does the same as `e`.
let g = pin!(NoMove(1, PhantomPinned));
println!("g: {:p}", &*g);
let h = g;
println!("h: {:p}", &*h);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment