Skip to content

Why does Pin::set take self by value? #57339

Closed
@HadrienG2

Description

@HadrienG2

Looking at https://doc.rust-lang.org/nightly/std/pin/struct.Pin.html, I see that Pin::set takes self by value. This is unlike the API that was proposed in the tracking issue #55766, which would take &mut self instead, and I could not find a rationale for this discrepancy in the tracking issue.

Is this intended? If not, you may want to fix this before the Pin stabilization actually hits beta/stable 😉

Activity

cramertj

cramertj commented on Jan 4, 2019

@cramertj
Member

This is what I implemented and what I intended when I implemented it, but I didn't notice the discrepancy with @withoutboats's stabilization report. If they feel that this should be changed, it seems worth discussing, otherwise I'm comfortable moving forward with it as-is. The choice here is whether or not to build-in reborrowing into the method or to require a call to .as_mut() to reborrow the Pin.

HadrienG2

HadrienG2 commented on Jan 4, 2019

@HadrienG2
Author

Just to make sure I understand the implications, does the following code behave as I expect?

use pin_utils::pin_mut;

fn main() {
    let x = Foo { ... };
    pin_mut!(x);
    x.set(Foo { ... })
    // Pin<&mut x> does not implement Copy because &mut _ is (obviously) not copyable
    // So x has been consumed and there is no way to access the underlying value anymore...
}

And if so, what is the intended use case for Pin::set()?

HadrienG2

HadrienG2 commented on Jan 4, 2019

@HadrienG2
Author

Oh, wait, I think I understand your earlier remark about as_mut(). Since &mut T implements DerefMut<Target=T>, this should work:

let x = Foo { ... };
pin_mut!(x);
let x2 = x.as_mut();
x2.set(Foo { ... });
// At this point, x2 has been destroyed, but the old x borrow becomes usable again

Coming from a world of pointers and references, it decidedly feels odd to need to manually reborrow like this in order to avoid losing access to the &mut by merely writing into it. But maybe I misunderstood something.

cramertj

cramertj commented on Jan 4, 2019

@cramertj
Member

It does feel odd to need to manually reborrow, and its unfortunate that Pin<&mut T> requires this, unlike &mut T which does it automatically. However, I hope this restriction will be lifted in the future.

HadrienG2

HadrienG2 commented on Jan 5, 2019

@HadrienG2
Author

I see, if the plan is to enable reborrow semantics later on it does make more sense !

withoutboats

withoutboats commented on Jan 5, 2019

@withoutboats
Contributor

Is there a reason you would not want reborrow semantics? The current API is technically the most "broad," but if what it enables is useless (I can't think of a use), we could just backport a change to the API.

withoutboats

withoutboats commented on Jan 5, 2019

@withoutboats
Contributor

(The discrepancy with the stabilization report was a mistake on my part I believe; I don't remember noting this and I didn't list it as a change to be made before stabilizing)

HadrienG2

HadrienG2 commented on Jan 5, 2019

@HadrienG2
Author

Sorry, I worded my last comment very poorly. What I meant is, if the plan is to eventually give Pin<&mut T> special semantics as a self type, so that self: Pin<&mut T> does not consume the Pin (like &mut self does not consume the reference), then I understand the design of this API better.

withoutboats

withoutboats commented on Jan 5, 2019

@withoutboats
Contributor

I was responding to the issue, not your last comment. I think it would be strictly better to make this change while we still can.

cramertj

cramertj commented on Jan 7, 2019

@cramertj
Member

@withoutboats I don't have any strong feelings either way. I'll open a PR to change and we can see if anyone opposes or otherwise merge it.

added a commit that references this issue on Jan 9, 2019

Auto merge of #57419 - cramertj:pin-set, r=withouboats

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @HadrienG2@cramertj@withoutboats

        Issue actions

          Why does Pin::set take self by value? · Issue #57339 · rust-lang/rust