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:
commit
fa4cfeb597
23 changed files with 250 additions and 54 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
33
src/test/ui/moves/move-deref-coercion.rs
Normal file
33
src/test/ui/moves/move-deref-coercion.rs
Normal 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() {}
|
||||
35
src/test/ui/moves/move-deref-coercion.stderr
Normal file
35
src/test/ui/moves/move-deref-coercion.stderr
Normal 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`.
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue