How to: Pin<Box<T>> -> T

Suppose I am done needing the Pin<Box<T>> in a program. How to I get T? I must move it at this point. Using Pin::into_inner does not seem to do the trick

Looks like this does the trick:

 let pinned: Pin<Box<T>> = Box::pin(my_obj);
 let unpinned = *Pin::into_inner(pinned);

Naturally this is only possible because your type is Unpin and therefore not self referential.

3 Likes

Yep, that's a good point. Forgot to mention that

When the pointee (here T) is Unpin, then Pin does nothing, you can transparently "unwrap" it with .get(), .get_mut() and .into_inner() (Rust trinity).

When the pointee is not Unpin, then the operation you require goes against the pinning guarantees (you are asking to move heap contents into a local / the stack). Depending on the type, you may be able to .clone() it and (implicitly) drop() the original.

To really move a potentially self-referential type you'd need to invoke custom code that would fix / update the self-references, which has some experimental work with the ::transfer and ::stackpin crates; cc their author @zrk

2 Likes

The self-references point to a fundamental type that is independent of the middle and higher-level abstractions. I just created a way to have both actix agents AND an async/await subroutine to execute. I needed to pass a pointer to a packet received by actix to the independently-running packet-handler. Thus, there are pointers to heap-pinned packets as well as the globally-accessible channel. It works as expected, and now I can use the actor model alongside async/await. :slight_smile:

Incase some are wondering: the actix actor-model does not allow for the embedding of async/await

There's virtually infinite degrees of architectural freedom once you safely use unsafe code to design a program. The downside of unsafe is that it will require the future programmer to know what's happening topologically (which can be confusing, but using consistent metaphors helps solve the complexity).

There are still many degrees of freedom in safe code, but sometimes it can be more difficult, and can make cohering to certain mental/metaphoric models as impossible.

Thank you for citing my work, keep in mind it is very experimental at this point, I really need to develop it further (publish dynref as an example crate, add !Sized support to stackpin and transfer, ...). I published the crates in a bit of a rough state, in the hope they would be useful to the community, as self referential structs are a recurring pain point in rust. If anyone has questions about the approach, I'd be glad to answer them at the best of my capacity in the dedicated thread :slight_smile:

From @nologik answer's though I gathered that they might not need !Unpin types at the moment?

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.