# ergo-pin

Immobilis ergo pin

**Ergo**nomic stack **pin**ning for Rust. `ergo-pin` exports a single proc-macro-attribute `#[ergo_pin]` that can be applied to a function/block/`tt`-accepting-macro-invocation to provide the "magical" `pin!` within the scope. You can consider this `pin!` macro equivalent to a function with the signature: ```rust extern "bla̴ck̀ mag̸ic͘" fn pin!(t: T) -> Pin<&'local mut T>; ``` it will take in any value and return a `Pin<&mut _>` of the value, with the correct local stack lifetime. ## Internals Internally the `pin!` macro works by injecting extra statements before the statement that contains it to create this `Pin`ned reference, it's probably easiest to see what it's doing by example. Given some code like ```rust #[ergo_pin] { quux(pin!(Foo::new().bar()).baz()); } ``` this will be re-written to ```rust { let mut __ergo_pin_0 = Foo::new().bar(); let __ergo_pin_0 = unsafe { ::core::pin::Pin::new_unchecked(&mut __ergo_pin_0) }; quux(__ergo_pin_0.baz()); } ``` The expression passed to `pin!` is first bound to a local variable, this is then shadowed by a `Pin`ned reference to itself (you may recognise this from the `pin-utils::pin_mut!` stack pinning macro), finally the `pin!` call is replaced with the local variable used. Since this requires re-writing code outside the macro this can't be implemented by as a normal `pin!` macro, which is why the main entrypoint is the `#[ergo_pin]` attribute. ## Rust Version Policy This crate only supports the current stable version of Rust, patch releases may use new features at any time. ## License Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.