Return Reference to Local Variable

Not really, Pin says that something behind a pinned reference can't move. Also, if you want to exploit Pin's gaurantees you must use unsafe. So it isn't Rust enforcing pins so much as it is you and some very clever unsafe libraries enforcing pins.

There remains no safe way to create an immovable type. You must use unsafe somewhere down the line and make sure that you type doesn't move manually. This is helped by libraries like pin-utils and pin-project, but they don't help with the fundemental problem.

The simplest immovable type is this,

pub struct Immovable {
    data: i32,
    data_ref: *mut i32
}

where data_ref points to data. If Rust has first class immovable types, we could do something like

struct Immovable {
    data: i32,
    data_ref: Option<&'data mut i32>
}

But we can't because Rust doesn't have first class immovable types.

1 Like

First class as in we could explicitly define a type to be immovable, rather than implicitly by using raw pointers within it?

Yes

This idea was considered around the same time that Pin was. It would have been a new trait, Move. But it was discarded because all generics would have to be rewritten to adapt to be compatible with !Move types. Every type would be Move by default, but we would have some way of opting out for compatibility. If we went that route, we would have truly immovable types, and we could have safe self-referential types (after some upgrades in the lifetime checker).

See this RFC for details

But I don't actually want completely immovable types - I only want the guarantees provided by Pin, right?
Say for example the Vec type - it contains a RawVec, and thus should be movable, right?
However, the actual data that I want to hold references to is stored in the heap - which is never moved.

Pin provides the same guarantees as immovable types (well, almost the same)

If a Vec reallocates, then things do move. But you have stated that the Vec won't be modified so that shouldn't be an issue. Here is the thing, the compile does not verify if the things behind a Pin do in fact remain immovable. Pin just makes it so that it is impossible to get a unique reference into itself via safe code if the pointee is is !Unpin.

1 Like

I believe that f() returns a temporary value of Extractor that owns the vector, which returns a reference to a slice of that vector when get is called. I thought this would work since I (mistakenly) thought that temporary get dropped at end of the scope. As I tested around a bit more and it seems that temporary value get dropped ASAP. So this would not be a solution except for the most trivial cases.

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