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

Closed
Nemo157 opened this issue Oct 14, 2019 · 8 comments · Fixed by #106095
Closed

Suggest as_mut to reborrow Pin when calling method #65409

Nemo157 opened this issue Oct 14, 2019 · 8 comments · Fixed by #106095
Labels
A-async-await Area: Async & Await A-borrow-checker Area: The borrow checker A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Nemo157
Copy link
Member

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 Centril added A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. A-borrow-checker Area: The borrow checker T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Oct 14, 2019
@Centril
Copy link
Contributor

Centril commented Oct 14, 2019

@nikomatsakis
Copy link
Contributor

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 Centril added the A-async-await Area: Async & Await label Oct 18, 2019
@Centril
Copy link
Contributor

Centril commented Oct 18, 2019

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

@nikomatsakis nikomatsakis added the AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. label Oct 22, 2019
@gilescope
Copy link
Contributor

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

@gilescope
Copy link
Contributor

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
Copy link
Member Author

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).

@dtolnay
Copy link
Member

dtolnay commented Jan 27, 2022

@rustbot release-assignment

@estebank
Copy link
Contributor

estebank commented Dec 23, 2022

Addressed the Pin<&mut T> case in #106095.

For the general case of suggesting .clone() can't be accomplished at this time because by the time borrowck comes around I can no longer use the inference context to evaluate T: Clone for an accurate suggestion.

Edit: Figured out a hack to suggest clone. That PR will close this ticket.

@bors bors closed this as completed in 0ca5003 Dec 27, 2022
Aaron1011 pushed a commit to Aaron1011/rust that referenced this issue Jan 6, 2023
…r-errors

Suggest `Pin::as_mut` when encountering borrow error

Fix rust-lang#65409 for `Pin<&mut T>`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await A-borrow-checker Area: The borrow checker A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
6 participants