Account for dereference expressions

This commit is contained in:
Esteban Küber 2022-12-09 13:01:41 -08:00
parent b8bd1d0826
commit cf0b6b9337
17 changed files with 208 additions and 140 deletions

View file

@ -410,13 +410,7 @@ fn report_cannot_move_from_borrowed_content(
fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diagnostic, span: Span) {
match error {
GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"consider borrowing here",
"&".to_string(),
Applicability::Unspecified,
);
self.add_borrow_suggestions(err, span);
if binds_to.is_empty() {
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
let place_desc = match self.describe_place(move_from.as_ref()) {
@ -459,6 +453,27 @@ fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diagnostic, sp
}
}
fn add_borrow_suggestions(&self, err: &mut Diagnostic, span: Span) {
match self.infcx.tcx.sess.source_map().span_to_snippet(span) {
Ok(snippet) if snippet.starts_with('*') => {
err.span_suggestion_verbose(
span.with_hi(span.lo() + BytePos(1)),
"consider removing the dereference here",
String::new(),
Applicability::MaybeIncorrect,
);
}
_ => {
err.span_suggestion_verbose(
span.shrink_to_lo(),
"consider borrowing here",
"&".to_string(),
Applicability::MaybeIncorrect,
);
}
}
}
fn add_move_error_suggestions(&self, err: &mut Diagnostic, binds_to: &[Local]) {
let mut suggestions: Vec<(Span, String, String)> = Vec::new();
for local in binds_to {

View file

@ -7,10 +7,11 @@ LL | match *s { S(v) => v }
| data moved here
| move occurs because `v` has type `Vec<isize>`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - match *s { S(v) => v }
LL + match s { S(v) => v }
|
LL | match &*s { S(v) => v }
| +
error: aborting due to previous error

View file

@ -0,0 +1,12 @@
// run-rustfix
fn main() {
let x: Option<Box<_>> = Some(Box::new(1));
match x {
Some(ref y) => {
let _b = y; //~ ERROR cannot move out
}
_ => {}
}
}

View file

@ -1,3 +1,4 @@
// run-rustfix
fn main() {
let x: Option<Box<_>> = Some(Box::new(1));

View file

@ -1,13 +1,14 @@
error[E0507]: cannot move out of `*y` which is behind a shared reference
--> $DIR/borrowck-issue-2657-2.rs:7:18
--> $DIR/borrowck-issue-2657-2.rs:8:18
|
LL | let _b = *y;
| ^^ move occurs because `*y` has type `Box<i32>`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let _b = *y;
LL + let _b = y;
|
LL | let _b = &*y;
| +
error: aborting due to previous error

View file

@ -10,7 +10,7 @@ enum Foo {
fn blah() {
let f = &Foo::Foo1(Box::new(1), Box::new(2));
match &*f { //~ ERROR cannot move out of
match f { //~ ERROR cannot move out of
Foo::Foo1(num1,
num2) => (),
Foo::Foo2(num) => (),

View file

@ -11,10 +11,11 @@ LL | Foo::Foo2(num) => (),
| --- ...and here
|
= note: move occurs because these variables have types that don't implement the `Copy` trait
help: consider borrowing here
help: consider removing the dereference here
|
LL - match *f {
LL + match f {
|
LL | match &*f {
| +
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-error-with-note.rs:30:11

View file

@ -4,10 +4,11 @@ error[E0507]: cannot move out of `*x` which is behind a raw pointer
LL | let y = *x;
| ^^ move occurs because `*x` has type `Box<isize>`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let y = *x;
LL + let y = x;
|
LL | let y = &*x;
| +
error: aborting due to previous error

View file

@ -4,10 +4,11 @@ error[E0507]: cannot move out of an `Rc`
LL | let _x = *Rc::new("hi".to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let _x = *Rc::new("hi".to_string());
LL + let _x = Rc::new("hi".to_string());
|
LL | let _x = &*Rc::new("hi".to_string());
| +
error: aborting due to previous error

View file

@ -4,10 +4,11 @@ error[E0507]: cannot move out of a mutable reference
LL | let a = unsafe { *mut_ref() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let a = unsafe { *mut_ref() };
LL + let a = unsafe { mut_ref() };
|
LL | let a = unsafe { &*mut_ref() };
| +
error[E0507]: cannot move out of a shared reference
--> $DIR/issue-20801.rs:29:22
@ -15,10 +16,11 @@ error[E0507]: cannot move out of a shared reference
LL | let b = unsafe { *imm_ref() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let b = unsafe { *imm_ref() };
LL + let b = unsafe { imm_ref() };
|
LL | let b = unsafe { &*imm_ref() };
| +
error[E0507]: cannot move out of a raw pointer
--> $DIR/issue-20801.rs:32:22
@ -26,10 +28,11 @@ error[E0507]: cannot move out of a raw pointer
LL | let c = unsafe { *mut_ptr() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let c = unsafe { *mut_ptr() };
LL + let c = unsafe { mut_ptr() };
|
LL | let c = unsafe { &*mut_ptr() };
| +
error[E0507]: cannot move out of a raw pointer
--> $DIR/issue-20801.rs:35:22
@ -37,10 +40,11 @@ error[E0507]: cannot move out of a raw pointer
LL | let d = unsafe { *const_ptr() };
| ^^^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let d = unsafe { *const_ptr() };
LL + let d = unsafe { const_ptr() };
|
LL | let d = unsafe { &*const_ptr() };
| +
error: aborting due to 4 previous errors

View file

@ -4,10 +4,11 @@ error[E0507]: cannot move out of `*array` which is behind a shared reference
LL | *array
| ^^^^^^ move occurs because `*array` has type `Vec<Value>`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - *array
LL + array
|
LL | &*array
| +
error: aborting due to previous error

View file

@ -7,10 +7,11 @@ LL | let [_, e, _, _] = *a;
| data moved here
| move occurs because `e` has type `D`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let [_, e, _, _] = *a;
LL + let [_, e, _, _] = a;
|
LL | let [_, e, _, _] = &*a;
| +
error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
--> $DIR/move-out-of-array-ref.rs:13:27
@ -21,10 +22,11 @@ LL | let [_, s @ .. , _] = *a;
| data moved here
| move occurs because `s` has type `[D; 2]`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let [_, s @ .. , _] = *a;
LL + let [_, s @ .. , _] = a;
|
LL | let [_, s @ .. , _] = &*a;
| +
error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
--> $DIR/move-out-of-array-ref.rs:18:24
@ -35,10 +37,11 @@ LL | let [_, e, _, _] = *a;
| data moved here
| move occurs because `e` has type `D`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let [_, e, _, _] = *a;
LL + let [_, e, _, _] = a;
|
LL | let [_, e, _, _] = &*a;
| +
error[E0508]: cannot move out of type `[D; 4]`, a non-copy array
--> $DIR/move-out-of-array-ref.rs:23:27
@ -49,10 +52,11 @@ LL | let [_, s @ .. , _] = *a;
| data moved here
| move occurs because `s` has type `[D; 2]`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let [_, s @ .. , _] = *a;
LL + let [_, s @ .. , _] = a;
|
LL | let [_, s @ .. , _] = &*a;
| +
error: aborting due to 4 previous errors

View file

@ -4,10 +4,11 @@ error[E0507]: cannot move out of `*r` which is behind a shared reference
LL | let x = { *r };
| ^^ move occurs because `*r` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let x = { *r };
LL + let x = { r };
|
LL | let x = { &*r };
| +
error[E0507]: cannot move out of `*r` which is behind a shared reference
--> $DIR/cannot-move-block-spans.rs:6:22
@ -15,10 +16,11 @@ error[E0507]: cannot move out of `*r` which is behind a shared reference
LL | let y = unsafe { *r };
| ^^ move occurs because `*r` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let y = unsafe { *r };
LL + let y = unsafe { r };
|
LL | let y = unsafe { &*r };
| +
error[E0507]: cannot move out of `*r` which is behind a shared reference
--> $DIR/cannot-move-block-spans.rs:7:26
@ -26,10 +28,11 @@ error[E0507]: cannot move out of `*r` which is behind a shared reference
LL | let z = loop { break *r; };
| ^^ move occurs because `*r` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let z = loop { break *r; };
LL + let z = loop { break r; };
|
LL | let z = loop { break &*r; };
| +
error[E0508]: cannot move out of type `[String; 2]`, a non-copy array
--> $DIR/cannot-move-block-spans.rs:11:15
@ -79,10 +82,11 @@ error[E0507]: cannot move out of `*r` which is behind a shared reference
LL | let x = { let mut u = 0; u += 1; *r };
| ^^ move occurs because `*r` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let x = { let mut u = 0; u += 1; *r };
LL + let x = { let mut u = 0; u += 1; r };
|
LL | let x = { let mut u = 0; u += 1; &*r };
| +
error[E0507]: cannot move out of `*r` which is behind a shared reference
--> $DIR/cannot-move-block-spans.rs:18:45
@ -90,10 +94,11 @@ error[E0507]: cannot move out of `*r` which is behind a shared reference
LL | let y = unsafe { let mut u = 0; u += 1; *r };
| ^^ move occurs because `*r` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let y = unsafe { let mut u = 0; u += 1; *r };
LL + let y = unsafe { let mut u = 0; u += 1; r };
|
LL | let y = unsafe { let mut u = 0; u += 1; &*r };
| +
error[E0507]: cannot move out of `*r` which is behind a shared reference
--> $DIR/cannot-move-block-spans.rs:19:49
@ -101,10 +106,11 @@ error[E0507]: cannot move out of `*r` which is behind a shared reference
LL | let z = loop { let mut u = 0; u += 1; break *r; u += 2; };
| ^^ move occurs because `*r` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let z = loop { let mut u = 0; u += 1; break *r; u += 2; };
LL + let z = loop { let mut u = 0; u += 1; break r; u += 2; };
|
LL | let z = loop { let mut u = 0; u += 1; break &*r; u += 2; };
| +
error: aborting due to 9 previous errors

View file

@ -4,10 +4,11 @@ error[E0507]: cannot move out of `*a` which is behind a shared reference
LL | let b = *a;
| ^^ move occurs because `*a` has type `A`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let b = *a;
LL + let b = a;
|
LL | let b = &*a;
| +
error[E0508]: cannot move out of type `[A; 1]`, a non-copy array
--> $DIR/move-errors.rs:12:13
@ -29,10 +30,11 @@ error[E0507]: cannot move out of `**r` which is behind a shared reference
LL | let s = **r;
| ^^^ move occurs because `**r` has type `A`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let s = **r;
LL + let s = *r;
|
LL | let s = &**r;
| +
error[E0507]: cannot move out of an `Rc`
--> $DIR/move-errors.rs:27:13
@ -40,10 +42,11 @@ error[E0507]: cannot move out of an `Rc`
LL | let s = *r;
| ^^ move occurs because value has type `A`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let s = *r;
LL + let s = r;
|
LL | let s = &*r;
| +
error[E0508]: cannot move out of type `[A; 1]`, a non-copy array
--> $DIR/move-errors.rs:32:13
@ -68,10 +71,11 @@ LL | let A(s) = *a;
| data moved here
| move occurs because `s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let A(s) = *a;
LL + let A(s) = a;
|
LL | let A(s) = &*a;
| +
error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
--> $DIR/move-errors.rs:44:19
@ -194,10 +198,11 @@ LL | Ok(s) | Err(s) => (),
| data moved here
| move occurs because `s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - match *x {
LL + match x {
|
LL | match &*x {
| +
error: aborting due to 14 previous errors

View file

@ -4,10 +4,11 @@ error[E0507]: cannot move out of a shared reference
LL | let x = *&x;
| ^^^ move occurs because value has type `std::sync::atomic::AtomicBool`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let x = *&x;
LL + let x = &x;
|
LL | let x = &*&x;
| +
error[E0507]: cannot move out of a shared reference
--> $DIR/std-uncopyable-atomics.rs:11:13
@ -15,10 +16,11 @@ error[E0507]: cannot move out of a shared reference
LL | let x = *&x;
| ^^^ move occurs because value has type `std::sync::atomic::AtomicIsize`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let x = *&x;
LL + let x = &x;
|
LL | let x = &*&x;
| +
error[E0507]: cannot move out of a shared reference
--> $DIR/std-uncopyable-atomics.rs:13:13
@ -26,10 +28,11 @@ error[E0507]: cannot move out of a shared reference
LL | let x = *&x;
| ^^^ move occurs because value has type `std::sync::atomic::AtomicUsize`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let x = *&x;
LL + let x = &x;
|
LL | let x = &*&x;
| +
error[E0507]: cannot move out of a shared reference
--> $DIR/std-uncopyable-atomics.rs:15:13
@ -37,10 +40,11 @@ error[E0507]: cannot move out of a shared reference
LL | let x = *&x;
| ^^^ move occurs because value has type `std::sync::atomic::AtomicPtr<usize>`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let x = *&x;
LL + let x = &x;
|
LL | let x = &*&x;
| +
error: aborting due to 4 previous errors

View file

@ -37,22 +37,22 @@ pub fn main() {
let X(_t) = *s;
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
if let Either::One(_t) = *r { }
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
while let Either::One(_t) = *r { }
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
match *r {
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
Either::One(_t)
| Either::Two(_t) => (),
}
match *r {
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
Either::One(_t) => (),
Either::Two(ref _t) => (),
// FIXME: should suggest removing `ref` too
@ -60,29 +60,29 @@ pub fn main() {
let X(_t) = *sm;
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
if let Either::One(_t) = *rm { }
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
while let Either::One(_t) = *rm { }
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
match *rm {
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
Either::One(_t)
| Either::Two(_t) => (),
}
match *rm {
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
Either::One(_t) => (),
Either::Two(ref _t) => (),
// FIXME: should suggest removing `ref` too
}
match *rm {
//~^ ERROR cannot move
//~| HELP consider borrowing here
//~| HELP consider removing the dereference here
Either::One(_t) => (),
Either::Two(ref mut _t) => (),
// FIXME: should suggest removing `ref` too

View file

@ -7,10 +7,11 @@ LL | let X(_t) = *s;
| data moved here
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let X(_t) = *s;
LL + let X(_t) = s;
|
LL | let X(_t) = &*s;
| +
error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference
--> $DIR/simple.rs:41:30
@ -21,10 +22,11 @@ LL | if let Either::One(_t) = *r { }
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - if let Either::One(_t) = *r { }
LL + if let Either::One(_t) = r { }
|
LL | if let Either::One(_t) = &*r { }
| +
error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference
--> $DIR/simple.rs:44:33
@ -35,10 +37,11 @@ LL | while let Either::One(_t) = *r { }
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - while let Either::One(_t) = *r { }
LL + while let Either::One(_t) = r { }
|
LL | while let Either::One(_t) = &*r { }
| +
error[E0507]: cannot move out of `r` as enum variant `Two` which is behind a shared reference
--> $DIR/simple.rs:47:11
@ -52,10 +55,11 @@ LL | Either::One(_t)
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - match *r {
LL + match r {
|
LL | match &*r {
| +
error[E0507]: cannot move out of `r` as enum variant `One` which is behind a shared reference
--> $DIR/simple.rs:53:11
@ -69,10 +73,11 @@ LL | Either::One(_t) => (),
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - match *r {
LL + match r {
|
LL | match &*r {
| +
error[E0507]: cannot move out of `sm` which is behind a mutable reference
--> $DIR/simple.rs:61:17
@ -83,10 +88,11 @@ LL | let X(_t) = *sm;
| data moved here
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - let X(_t) = *sm;
LL + let X(_t) = sm;
|
LL | let X(_t) = &*sm;
| +
error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference
--> $DIR/simple.rs:64:30
@ -97,10 +103,11 @@ LL | if let Either::One(_t) = *rm { }
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - if let Either::One(_t) = *rm { }
LL + if let Either::One(_t) = rm { }
|
LL | if let Either::One(_t) = &*rm { }
| +
error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference
--> $DIR/simple.rs:67:33
@ -111,10 +118,11 @@ LL | while let Either::One(_t) = *rm { }
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - while let Either::One(_t) = *rm { }
LL + while let Either::One(_t) = rm { }
|
LL | while let Either::One(_t) = &*rm { }
| +
error[E0507]: cannot move out of `rm` as enum variant `Two` which is behind a mutable reference
--> $DIR/simple.rs:70:11
@ -128,10 +136,11 @@ LL | Either::One(_t)
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - match *rm {
LL + match rm {
|
LL | match &*rm {
| +
error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference
--> $DIR/simple.rs:76:11
@ -145,10 +154,11 @@ LL | Either::One(_t) => (),
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - match *rm {
LL + match rm {
|
LL | match &*rm {
| +
error[E0507]: cannot move out of `rm` as enum variant `One` which is behind a mutable reference
--> $DIR/simple.rs:83:11
@ -162,10 +172,11 @@ LL | Either::One(_t) => (),
| data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing here
help: consider removing the dereference here
|
LL - match *rm {
LL + match rm {
|
LL | match &*rm {
| +
error[E0507]: cannot move out of index of `Vec<X>`
--> $DIR/simple.rs:91:17