Rollup merge of #75304 - Aaron1011:feature/diag-deref-move-out, r=estebank

Note when a a move/borrow error is caused by a deref coercion

Fixes #73268

When a deref coercion occurs, we may end up with a move error if the
base value has been partially moved out of. However, we do not indicate
anywhere that a deref coercion is occuring, resulting in an error
message with a confusing span.

This PR adds an explicit note to move errors when a deref coercion is
involved. We mention the name of the type that the deref-coercion
resolved to, as well as the `Deref::Target` associated type being used.
This commit is contained in:
Dylan DPC 2020-09-16 01:30:32 +02:00 committed by GitHub
commit fa4cfeb597
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 250 additions and 54 deletions

View file

@ -149,7 +149,7 @@ error: function cannot return without recursing
LL | fn deref(&self) -> &Baz {
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
LL | self.as_ref()
| ---- recursive call site
| ------------- recursive call site
|
= help: a `loop` may express intention better if this is on purpose

View file

@ -0,0 +1,33 @@
use std::ops::Deref;
struct NotCopy {
inner: bool
}
impl NotCopy {
fn inner_method(&self) {}
}
struct Foo {
first: NotCopy,
second: NotCopy
}
impl Deref for Foo {
type Target = NotCopy;
fn deref(&self) -> &NotCopy {
&self.second
}
}
fn use_field(val: Foo) {
let _val = val.first;
val.inner; //~ ERROR borrow of
}
fn use_method(val: Foo) {
let _val = val.first;
val.inner_method(); //~ ERROR borrow of
}
fn main() {}

View file

@ -0,0 +1,35 @@
error[E0382]: borrow of partially moved value: `val`
--> $DIR/move-deref-coercion.rs:25:5
|
LL | let _val = val.first;
| --------- value partially moved here
LL | val.inner;
| ^^^^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `val.first` has type `NotCopy`, which does not implement the `Copy` trait
= note: borrow occurs due to deref coercion to `NotCopy`
note: deref defined here
--> $DIR/move-deref-coercion.rs:17:5
|
LL | type Target = NotCopy;
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0382]: borrow of partially moved value: `val`
--> $DIR/move-deref-coercion.rs:30:5
|
LL | let _val = val.first;
| --------- value partially moved here
LL | val.inner_method();
| ^^^^^^^^^^^^^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `val.first` has type `NotCopy`, which does not implement the `Copy` trait
= note: borrow occurs due to deref coercion to `NotCopy`
note: deref defined here
--> $DIR/move-deref-coercion.rs:17:5
|
LL | type Target = NotCopy;
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0382`.

View file

@ -1,5 +1,5 @@
error[E0382]: borrow of moved value: `arc_v`
--> $DIR/no-capture-arc.rs:14:18
--> $DIR/no-capture-arc.rs:14:16
|
LL | let arc_v = Arc::new(v);
| ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
@ -10,7 +10,14 @@ LL | assert_eq!((*arc_v)[3], 4);
| ----- variable moved due to use in closure
...
LL | assert_eq!((*arc_v)[2], 3);
| ^^^^^ value borrowed here after move
| ^^^^^^^^ value borrowed here after move
|
= note: borrow occurs due to deref coercion to `Vec<i32>`
note: deref defined here
--> $SRC_DIR/alloc/src/sync.rs:LL:COL
|
LL | type Target = T;
| ^^^^^^^^^^^^^^^^
error: aborting due to previous error

View file

@ -1,5 +1,5 @@
error[E0382]: borrow of moved value: `arc_v`
--> $DIR/no-reuse-move-arc.rs:12:18
--> $DIR/no-reuse-move-arc.rs:12:16
|
LL | let arc_v = Arc::new(v);
| ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
@ -10,7 +10,14 @@ LL | assert_eq!((*arc_v)[3], 4);
| ----- variable moved due to use in closure
...
LL | assert_eq!((*arc_v)[2], 3);
| ^^^^^ value borrowed here after move
| ^^^^^^^^ value borrowed here after move
|
= note: borrow occurs due to deref coercion to `Vec<i32>`
note: deref defined here
--> $SRC_DIR/alloc/src/sync.rs:LL:COL
|
LL | type Target = T;
| ^^^^^^^^^^^^^^^^
error: aborting due to previous error