En Rust, std::pin::Pin es un envoltorio de puntero que garantiza, mediante el sistema de tipos, que el valor apuntado no se moverá a través de ese puntero. Su razón de ser está en los tipos autorreferenciales, estructuras que contienen punteros crudos hacia sus propios campos: si la instancia se mueve en memoria, esos punteros internos quedan colgando y se produce comportamiento indefinido.
El caso más habitual aparece con async/await. Las variables locales que sobreviven a un punto .await se convierten en campos del estado generado por el compilador; si una referencia a una de ellas también sobrevive, el Future resultante es autorreferencial. Por eso el método Future::poll recibe Pin<&mut Self>: una vez iniciado el sondeo, el Future no puede moverse.
Pin actúa a nivel de tipos, no físicamente: impide que código seguro recupere un &mut T que permita reubicar el valor. Si el tipo implementa Unpin (auto-trait que casi todos los tipos reciben por defecto), Pin no aporta garantías; solo cuando el tipo es !Unpin la restricción es efectiva. El marcador PhantomPinned permite declarar explícitamente que un struct no es Unpin, lo que obliga al desarrollador a asumir la responsabilidad de no moverlo.
Para construir un Pin en código seguro existen tres caminos principales. Pin::new sirve con tipos Unpin; el macro pin! crea un Pin<&mut T> ligado a una variable local de pila; y Box::pin devuelve un Pin> válido para tipos !Unpin, ya que la asignación en el montón no cambia de dirección. En código unsafe se puede usar Pin::new_unchecked, con la promesa explícita de que el valor no se moverá.
En la práctica diaria, la mayoría de desarrolladores solo necesita pin! o Box::pin al consumir Futures, y recurrir a PhantomPinned y APIs unsafe únicamente al implementar abstracciones asíncronas de bajo nivel. Pin es, en definitiva, la solución de coste cero de Rust para los tipos sensibles a la dirección de memoria, sin necesidad de recolector de basura.
