Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest as_mut to reborrow Pin when calling method #65409

Open
Nemo157 opened this issue Oct 14, 2019 · 6 comments

Comments

@Nemo157
Copy link
Contributor

@Nemo157 Nemo157 commented Oct 14, 2019

I have seen a lot of newcomers to futures stumble with Pin<&mut Self> methods consuming the pin, if possible this seems like a good candidate for a custom diagnostic.

As a self-contained example (playground):

use std::pin::Pin;

struct Foo;

impl Foo {
    fn foo(self: Pin<&mut Self>) {}
}

fn main() {
    let mut foo = Foo;
    let foo = Pin::new(&mut foo);
    foo.foo();
    foo.foo();
}

currently errors with

   Compiling playground v0.0.1 (/playground)
error[E0382]: use of moved value: `foo`
  --> src/main.rs:13:5
   |
11 |     let foo = Pin::new(&mut foo);
   |         --- move occurs because `foo` has type `std::pin::Pin<&mut Foo>`, which does not implement the `Copy` trait
12 |     foo.foo();
   |     --- value moved here
13 |     foo.foo();
   |     ^^^ value used here after move

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.
error: Could not compile `playground`.

To learn more, run the command again with --verbose.

it would be useful if this error included something like

hint: use `foo.as_mut().foo()` to reborrow the `Pin` instead of moving it
@Centril

This comment has been minimized.

Copy link
Member

@Centril Centril commented Oct 14, 2019

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

@nikomatsakis nikomatsakis commented Oct 18, 2019

Seems reasonable to me. Should we tag this A-async-await? Seems to fall under the "async foundations" purview, anyway. (Slight mismatch between those labels, I guess)

@Centril

This comment has been minimized.

Copy link
Member

@Centril Centril commented Oct 18, 2019

@nikomatsakis Yes, let's. Any thoughts re. implementation? ;)

@gilescope

This comment has been minimized.

Copy link
Contributor

@gilescope gilescope commented Oct 30, 2019

Happy to give this one a go - the hint would certainly help me if I stumbled into this.
@rustbot claim

@gilescope

This comment has been minimized.

Copy link
Contributor

@gilescope gilescope commented Nov 5, 2019

Rather than being specific to Pin, can we expand the scope and add a hint to the general error message:

      hint: consider [mutably] borrowing '&[mut ]foo' [or foo.clone()] here?
                                                        ^ only suggest if T:Clone

and if possible specialise the error message if the type supports as_ref()/as_mut()?

As a user, that's the kind of error message I'd be greatful to receive - a hint as to whether the type is clonable or not and if there's a as_mut() call I could be using rather than trying to &mut it.

@Nemo157

This comment has been minimized.

Copy link
Contributor Author

@Nemo157 Nemo157 commented Nov 5, 2019

For normal &self/&mut self methods the compiler will implicitly reborrow. If there’s a generalisation here that could help suggest cloning that sounds good to me (small playground to check the current error message).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.