diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2020-06-25 18:00:10 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-25 18:00:10 -0700 |
| commit | 4a245aeec5e7ef71002f91ef9e00eb24646c6ea4 (patch) | |
| tree | 841b3c1ce244c56121be9e51fc23fd286d3f450b /src/test | |
| parent | 3f5b8c800e546809b374aecad992689712ab00d6 (diff) | |
| parent | 520461f1fb2730f8edb17922f3bcc74fccdc52d3 (diff) | |
| download | rust-4a245aeec5e7ef71002f91ef9e00eb24646c6ea4.tar.gz rust-4a245aeec5e7ef71002f91ef9e00eb24646c6ea4.zip | |
Rollup merge of #73534 - estebank:borrowck-suggestions, r=matthewjasper
Provide suggestions for some moved value errors When encountering an used moved value where the previous move happened in a `match` or `if let` pattern, suggest using `ref`. Fix #63988. When encountering a `&mut` value that is used in multiple iterations of a loop, suggest reborrowing it with `&mut *`. Fix #62112.
Diffstat (limited to 'src/test')
14 files changed, 264 insertions, 0 deletions
diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr index 422d1605aa4..604143b4e7e 100644 --- a/src/test/ui/borrowck/issue-41962.stderr +++ b/src/test/ui/borrowck/issue-41962.stderr @@ -5,6 +5,10 @@ LL | if let Some(thing) = maybe { | ^^^^^ value moved here, in previous iteration of loop | = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `maybe.0` + | +LL | if let Some(ref thing) = maybe { + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/borrowck/move-in-pattern-mut.rs b/src/test/ui/borrowck/move-in-pattern-mut.rs new file mode 100644 index 00000000000..175eb3b7a04 --- /dev/null +++ b/src/test/ui/borrowck/move-in-pattern-mut.rs @@ -0,0 +1,23 @@ +// Issue #63988 +#[derive(Debug)] +struct S; +fn foo(_: Option<S>) {} + +enum E { + V { + s: S, + } +} +fn bar(_: E) {} + +fn main() { + let s = Some(S); + if let Some(mut x) = s { + x = S; + } + foo(s); //~ ERROR use of moved value: `s` + let mut e = E::V { s: S }; + let E::V { s: mut x } = e; + x = S; + bar(e); //~ ERROR use of moved value: `e` +} diff --git a/src/test/ui/borrowck/move-in-pattern-mut.stderr b/src/test/ui/borrowck/move-in-pattern-mut.stderr new file mode 100644 index 00000000000..391638444c3 --- /dev/null +++ b/src/test/ui/borrowck/move-in-pattern-mut.stderr @@ -0,0 +1,33 @@ +error[E0382]: use of moved value: `s` + --> $DIR/move-in-pattern-mut.rs:18:9 + | +LL | if let Some(mut x) = s { + | ----- value moved here +... +LL | foo(s); + | ^ value used here after partial move + | + = note: move occurs because value has type `S`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `s.0` + | +LL | if let Some(ref mut x) = s { + | ^^^ + +error[E0382]: use of moved value: `e` + --> $DIR/move-in-pattern-mut.rs:22:9 + | +LL | let E::V { s: mut x } = e; + | ----- value moved here +LL | x = S; +LL | bar(e); + | ^ value used here after partial move + | + = note: move occurs because value has type `S`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `e.s` + | +LL | let E::V { s: ref mut x } = e; + | ^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/move-in-pattern.fixed b/src/test/ui/borrowck/move-in-pattern.fixed new file mode 100644 index 00000000000..f55fdcc5f90 --- /dev/null +++ b/src/test/ui/borrowck/move-in-pattern.fixed @@ -0,0 +1,24 @@ +// run-rustfix +// Issue #63988 +#[derive(Debug)] +struct S; +fn foo(_: Option<S>) {} + +enum E { + V { + s: S, + } +} +fn bar(_: E) {} + +fn main() { + let s = Some(S); + if let Some(ref x) = s { + let _ = x; + } + foo(s); //~ ERROR use of moved value: `s` + let e = E::V { s: S }; + let E::V { s: ref x } = e; + let _ = x; + bar(e); //~ ERROR use of moved value: `e` +} diff --git a/src/test/ui/borrowck/move-in-pattern.rs b/src/test/ui/borrowck/move-in-pattern.rs new file mode 100644 index 00000000000..7ad04b9490c --- /dev/null +++ b/src/test/ui/borrowck/move-in-pattern.rs @@ -0,0 +1,24 @@ +// run-rustfix +// Issue #63988 +#[derive(Debug)] +struct S; +fn foo(_: Option<S>) {} + +enum E { + V { + s: S, + } +} +fn bar(_: E) {} + +fn main() { + let s = Some(S); + if let Some(x) = s { + let _ = x; + } + foo(s); //~ ERROR use of moved value: `s` + let e = E::V { s: S }; + let E::V { s: x } = e; + let _ = x; + bar(e); //~ ERROR use of moved value: `e` +} diff --git a/src/test/ui/borrowck/move-in-pattern.stderr b/src/test/ui/borrowck/move-in-pattern.stderr new file mode 100644 index 00000000000..c5cb24455eb --- /dev/null +++ b/src/test/ui/borrowck/move-in-pattern.stderr @@ -0,0 +1,33 @@ +error[E0382]: use of moved value: `s` + --> $DIR/move-in-pattern.rs:19:9 + | +LL | if let Some(x) = s { + | - value moved here +... +LL | foo(s); + | ^ value used here after partial move + | + = note: move occurs because value has type `S`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `s.0` + | +LL | if let Some(ref x) = s { + | ^^^ + +error[E0382]: use of moved value: `e` + --> $DIR/move-in-pattern.rs:23:9 + | +LL | let E::V { s: x } = e; + | - value moved here +LL | let _ = x; +LL | bar(e); + | ^ value used here after partial move + | + = note: move occurs because value has type `S`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `e.s` + | +LL | let E::V { s: ref x } = e; + | ^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/mut-borrow-in-loop-2.fixed b/src/test/ui/borrowck/mut-borrow-in-loop-2.fixed new file mode 100644 index 00000000000..ceeba30a90f --- /dev/null +++ b/src/test/ui/borrowck/mut-borrow-in-loop-2.fixed @@ -0,0 +1,35 @@ +// run-rustfix +#![allow(dead_code)] + +struct Events<R>(R); + +struct Other; + +pub trait Trait<T> { + fn handle(value: T) -> Self; +} + +// Blanket impl. (If you comment this out, compiler figures out that it +// is passing an `&mut` to a method that must be expecting an `&mut`, +// and injects an auto-reborrow.) +impl<T, U> Trait<U> for T where T: From<U> { + fn handle(_: U) -> Self { unimplemented!() } +} + +impl<'a, R> Trait<&'a mut Events<R>> for Other { + fn handle(_: &'a mut Events<R>) -> Self { unimplemented!() } +} + +fn this_compiles<'a, R>(value: &'a mut Events<R>) { + for _ in 0..3 { + Other::handle(&mut *value); + } +} + +fn this_does_not<'a, R>(value: &'a mut Events<R>) { + for _ in 0..3 { + Other::handle(&mut *value); //~ ERROR use of moved value: `value` + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/mut-borrow-in-loop-2.rs b/src/test/ui/borrowck/mut-borrow-in-loop-2.rs new file mode 100644 index 00000000000..d13fb7e5679 --- /dev/null +++ b/src/test/ui/borrowck/mut-borrow-in-loop-2.rs @@ -0,0 +1,35 @@ +// run-rustfix +#![allow(dead_code)] + +struct Events<R>(R); + +struct Other; + +pub trait Trait<T> { + fn handle(value: T) -> Self; +} + +// Blanket impl. (If you comment this out, compiler figures out that it +// is passing an `&mut` to a method that must be expecting an `&mut`, +// and injects an auto-reborrow.) +impl<T, U> Trait<U> for T where T: From<U> { + fn handle(_: U) -> Self { unimplemented!() } +} + +impl<'a, R> Trait<&'a mut Events<R>> for Other { + fn handle(_: &'a mut Events<R>) -> Self { unimplemented!() } +} + +fn this_compiles<'a, R>(value: &'a mut Events<R>) { + for _ in 0..3 { + Other::handle(&mut *value); + } +} + +fn this_does_not<'a, R>(value: &'a mut Events<R>) { + for _ in 0..3 { + Other::handle(value); //~ ERROR use of moved value: `value` + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr b/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr new file mode 100644 index 00000000000..fa1b741394a --- /dev/null +++ b/src/test/ui/borrowck/mut-borrow-in-loop-2.stderr @@ -0,0 +1,17 @@ +error[E0382]: use of moved value: `value` + --> $DIR/mut-borrow-in-loop-2.rs:31:23 + | +LL | fn this_does_not<'a, R>(value: &'a mut Events<R>) { + | ----- move occurs because `value` has type `&mut Events<R>`, which does not implement the `Copy` trait +LL | for _ in 0..3 { +LL | Other::handle(value); + | ^^^^^ value moved here, in previous iteration of loop + | +help: consider creating a fresh reborrow of `value` here + | +LL | Other::handle(&mut *value); + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr b/src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr index fb8562d00ea..952985fcdde 100644 --- a/src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr +++ b/src/test/ui/moves/moves-based-on-type-cyclic-types-issue-4821.stderr @@ -8,6 +8,10 @@ LL | consume(node) + r | ^^^^ value used here after partial move | = note: move occurs because value has type `std::boxed::Box<List>`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `node.next.0` + | +LL | Some(ref right) => consume(right), + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/nll/issue-53807.stderr b/src/test/ui/nll/issue-53807.stderr index 2b15da3710e..4f36a4ccab2 100644 --- a/src/test/ui/nll/issue-53807.stderr +++ b/src/test/ui/nll/issue-53807.stderr @@ -5,6 +5,10 @@ LL | if let Some(thing) = maybe { | ^^^^^ value moved here, in previous iteration of loop | = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `maybe.0` + | +LL | if let Some(ref thing) = maybe { + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr index f2186b9298e..8a6ea8e91a2 100644 --- a/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr +++ b/src/test/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr @@ -46,6 +46,10 @@ LL | Some(_z @ ref _y) => {} | value moved here | = note: move occurs because value has type `X`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `x.0` + | +LL | Some(ref _z @ ref _y) => {} + | ^^^ error[E0382]: borrow of moved value --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:19 @@ -57,6 +61,10 @@ LL | Some(_z @ ref mut _y) => {} | value moved here | = note: move occurs because value has type `X`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `x.0` + | +LL | Some(ref _z @ ref mut _y) => {} + | ^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index f819e671436..5058998f2a7 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -357,6 +357,10 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | value moved here | = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving the value + | +LL | a @ Some((ref mut b @ ref mut c, d @ ref e)) => {} + | ^^^ error[E0382]: use of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:38 @@ -379,6 +383,10 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | value moved here | = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving the value + | +LL | a @ Some((mut b @ ref mut c, ref d @ ref e)) => {} + | ^^^ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:71:30 @@ -412,6 +420,10 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | value moved here | = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving the value + | +LL | a @ Some((ref mut b @ ref mut c, d @ ref e)) => {} + | ^^^ error[E0382]: use of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:83:38 @@ -434,6 +446,10 @@ LL | a @ Some((mut b @ ref mut c, d @ ref e)) => {} | value moved here | = note: move occurs because value has type `main::U`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving the value + | +LL | a @ Some((mut b @ ref mut c, ref d @ ref e)) => {} + | ^^^ error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:93:30 diff --git a/src/test/ui/ref-suggestion.stderr b/src/test/ui/ref-suggestion.stderr index 9ff8e21bb58..97d2c174d9a 100644 --- a/src/test/ui/ref-suggestion.stderr +++ b/src/test/ui/ref-suggestion.stderr @@ -28,6 +28,10 @@ LL | x; | ^ value used here after partial move | = note: move occurs because value has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait +help: borrow this field in the pattern to avoid moving `x.0.0` + | +LL | (Some(ref y), ()) => {}, + | ^^^ error: aborting due to 3 previous errors |
