Skip to content

Commit

Permalink
Suggest Pin::as_mut when encountering borrow error
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Dec 23, 2022
1 parent 984eab5 commit c79db9c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 0 deletions.
11 changes: 11 additions & 0 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
place_name, partially_str, loop_message
),
);
if let ty::Adt(def, ..)
= moved_place.ty(self.body, self.infcx.tcx).ty.kind()
&& Some(def.did()) == self.infcx.tcx.lang_items().pin_type()
{
err.span_suggestion_verbose(
fn_call_span.shrink_to_lo(),
"consider reborrowing the `Pin` instead of moving it",
"as_mut().".to_string(),
Applicability::MaybeIncorrect,
);
}
}
let tcx = self.infcx.tcx;
// Avoid pointing to the same function in multiple different
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/moves/move-fn-self-receiver.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ note: `Foo::use_pin_box_self` takes ownership of the receiver `self`, which move
|
LL | fn use_pin_box_self(self: Pin<Box<Self>>) {}
| ^^^^
help: consider reborrowing the `Pin` instead of moving it
|
LL | pin_box_foo.as_mut().use_pin_box_self();
| +++++++++

error[E0505]: cannot move out of `mut_foo` because it is borrowed
--> $DIR/move-fn-self-receiver.rs:50:5
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/moves/pin-mut-reborrow.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// run-rustfix
use std::pin::Pin;

struct Foo;

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

fn main() {
let mut foo = Foo;
let mut foo = Pin::new(&mut foo);
foo.as_mut().foo();
foo.foo(); //~ ERROR use of moved value
}
15 changes: 15 additions & 0 deletions src/test/ui/moves/pin-mut-reborrow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// run-rustfix
use std::pin::Pin;

struct Foo;

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

fn main() {
let mut foo = Foo;
let mut foo = Pin::new(&mut foo);
foo.foo();
foo.foo(); //~ ERROR use of moved value
}
23 changes: 23 additions & 0 deletions src/test/ui/moves/pin-mut-reborrow.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error[E0382]: use of moved value: `foo`
--> $DIR/pin-mut-reborrow.rs:14:5
|
LL | let mut foo = Pin::new(&mut foo);
| ------- move occurs because `foo` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
LL | foo.foo();
| ----- `foo` moved due to this method call
LL | foo.foo();
| ^^^ value used here after move
|
note: `Foo::foo` takes ownership of the receiver `self`, which moves `foo`
--> $DIR/pin-mut-reborrow.rs:7:12
|
LL | fn foo(self: Pin<&mut Self>) {}
| ^^^^
help: consider reborrowing the `Pin` instead of moving it
|
LL | foo.as_mut().foo();
| +++++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.

0 comments on commit c79db9c

Please sign in to comment.