Auto merge of #51729 - matthewjasper:move-errors, r=nikomatsakis

[NLL] Better move errors

Make a number of changes to improve the quality of NLL cannot move errors.

* Group errors that occur in the same `match` with the same cause.
* Suggest `ref`, `&` or removing `*` to avoid the move.
* Show the place being matched on.

Differences from AST borrowck:

* `&` is suggested over `ref` when matching on a place that can't be moved from.
* Removing `*` is suggested instead of adding `&` when applicable.
* Sub-pattern spans aren't used, this would probably need Spans on Places.

Closes #45699
Closes #46627
Closes #51187
Closes #51189

r? @pnkfelix
This commit is contained in:
bors 2018-06-29 12:40:12 +00:00
commit ab8a67c12a
42 changed files with 997 additions and 321 deletions

View file

@ -18,9 +18,9 @@ impl Drop for S {
fn move_in_match() {
match (S {f:"foo".to_string()}) {
//[mir]~^ ERROR [E0509]
S {f:_s} => {}
//[ast]~^ ERROR cannot move out of type `S`, which implements the `Drop` trait [E0509]
//[mir]~^^ ERROR [E0509]
}
}

View file

@ -21,13 +21,13 @@ fn main() {
// END RUST SOURCE
// START rustc.norm2.InstCombine.before.mir
// _5 = Len(_1);
// _4 = Len(_1);
// ...
// _10 = Len(_1);
// _8 = Len(_1);
// END rustc.norm2.InstCombine.before.mir
// START rustc.norm2.InstCombine.after.mir
// _5 = const 2usize;
// _4 = const 2usize;
// ...
// _10 = const 2usize;
// _8 = const 2usize;
// END rustc.norm2.InstCombine.after.mir

View file

@ -22,12 +22,9 @@ fn main() {
// START rustc.test.CopyPropagation.before.mir
// bb0: {
// ...
// _3 = _1;
// _2 = _1;
// ...
// _2 = move _3;
// ...
// _4 = _2;
// _0 = move _4;
// _0 = _2;
// ...
// return;
// }
@ -35,7 +32,7 @@ fn main() {
// START rustc.test.CopyPropagation.after.mir
// bb0: {
// ...
// _0 = move _1;
// _0 = _1;
// ...
// return;
// }

View file

@ -117,13 +117,11 @@ fn main() {
// START rustc.arg_src.CopyPropagation.before.mir
// bb0: {
// ...
// _3 = _1;
// _2 = move _3;
// _2 = _1;
// ...
// _1 = const 123i32;
// ...
// _4 = _2;
// _0 = move _4;
// _0 = _2;
// ...
// return;
// }
@ -131,11 +129,11 @@ fn main() {
// START rustc.arg_src.CopyPropagation.after.mir
// bb0: {
// ...
// _3 = _1;
// _2 = _1;
// ...
// _1 = const 123i32;
// ...
// _0 = move _3;
// _0 = _2;
// ...
// return;
// }

View file

@ -68,13 +68,9 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir
// fn main::{{closure}}(_1: [closure@NodeId(18) d:&'14s D]) -> i32 {
// let mut _0: i32;
// let mut _2: i32;
//
// bb0: {
// StorageLive(_2);
// _2 = ((*(_1.0: &'14s D)).0: i32);
// _0 = move _2;
// StorageDead(_2);
// _0 = ((*(_1.0: &'14s D)).0: i32);
// return;
// }
// END rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir

View file

@ -70,14 +70,10 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// ...
// let _2: &'16_0rs D;
// ...
// let mut _3: i32;
// bb0: {
// StorageLive(_2);
// _2 = &'16_0rs (*(_1.0: &'19s D));
// StorageLive(_3);
// _3 = ((*_2).0: i32);
// _0 = move _3;
// StorageDead(_3);
// _0 = ((*_2).0: i32);
// EndRegion('16_0rs);
// StorageDead(_2);
// return;

View file

@ -78,14 +78,10 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// ...
// let _2: &'16_0rs D;
// ...
// let mut _3: i32;
// bb0: {
// StorageLive(_2);
// _2 = &'16_0rs (_1.0: D);
// StorageLive(_3);
// _3 = ((*_2).0: i32);
// _0 = move _3;
// StorageDead(_3);
// _0 = ((*_2).0: i32);
// EndRegion('16_0rs);
// StorageDead(_2);
// drop(_1) -> [return: bb2, unwind: bb1];

View file

@ -76,13 +76,9 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
// START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir
// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'19s D]) -> i32 {
// let mut _0: i32;
// let mut _2: i32;
//
// bb0: {
// StorageLive(_2);
// _2 = ((*(_1.0: &'21_1rs D)).0: i32);
// _0 = move _2;
// StorageDead(_2);
// _0 = ((*(_1.0: &'21_1rs D)).0: i32);
// return;
// }
// }

View file

@ -65,52 +65,45 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
// START rustc.main.QualifyAndPromoteConstants.before.mir
// fn main() -> () {
// let mut _0: ();
// let mut _0: ();
// let mut _1: &'12ds S1;
// let mut _2: &'12ds S1;
// let mut _3: D1<'12ds, '10s>;
// let mut _2: D1<'12ds, '10s>;
// let mut _3: &'12ds S1;
// let mut _4: &'12ds S1;
// let mut _5: &'12ds S1;
// let mut _6: S1;
// let mut _5: S1;
// let mut _6: &'10s S1;
// let mut _7: &'10s S1;
// let mut _8: &'10s S1;
// let mut _9: S1;
//
// let mut _8: S1;
// bb0: {
// StorageLive(_2);
// StorageLive(_3);
// StorageLive(_4);
// StorageLive(_5);
// _5 = S1::{{constructor}}(const "ex1",);
// _4 = &'12ds _5;
// _3 = &'12ds (*_4);
// StorageLive(_6);
// _6 = S1::{{constructor}}(const "ex1",);
// _5 = &'12ds _6;
// _4 = &'12ds (*_5);
// StorageLive(_7);
// StorageLive(_8);
// StorageLive(_9);
// _9 = S1::{{constructor}}(const "dang1",);
// _8 = &'10s _9;
// _7 = &'10s (*_8);
// _3 = D1<'12ds, '10s>::{{constructor}}(move _4, move _7);
// _8 = S1::{{constructor}}(const "dang1",);
// _7 = &'10s _8;
// _6 = &'10s (*_7);
// _2 = D1<'12ds, '10s>::{{constructor}}(move _3, move _6);
// EndRegion('10s);
// StorageDead(_7);
// StorageDead(_4);
// _2 = (_3.0: &'12ds S1);
// _1 = move _2;
// StorageDead(_2);
// drop(_3) -> [return: bb2, unwind: bb1];
// StorageDead(_6);
// StorageDead(_3);
// _1 = (_2.0: &'12ds S1);
// drop(_2) -> [return: bb2, unwind: bb1];
// }
//
// bb1: {
// resume;
// }
//
// bb2: {
// StorageDead(_3);
// StorageDead(_2);
// StorageDead(_7);
// StorageDead(_8);
// StorageDead(_9);
// StorageDead(_4);
// StorageDead(_5);
// StorageDead(_6);
// EndRegion('12ds);
// _0 = ();
// return;
@ -119,51 +112,44 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> {
// END rustc.main.QualifyAndPromoteConstants.before.mir
// START rustc.main.QualifyAndPromoteConstants.after.mir
// fn main() -> () {
// fn main() -> (){
// let mut _0: ();
// let mut _1: &'12ds S1;
// let mut _2: &'12ds S1;
// let mut _3: D1<'12ds, '10s>;
// let mut _2: D1<'12ds, '10s>;
// let mut _3: &'12ds S1;
// let mut _4: &'12ds S1;
// let mut _5: &'12ds S1;
// let mut _6: S1;
// let mut _5: S1;
// let mut _6: &'10s S1;
// let mut _7: &'10s S1;
// let mut _8: &'10s S1;
// let mut _9: S1;
// let mut _10: &'10s S1;
// let mut _11: &'12ds S1;
//
// let mut _8: S1;
// let mut _9: &'10s S1;
// let mut _10: &'12ds S1;
// bb0: {
// StorageLive(_2);
// StorageLive(_3);
// StorageLive(_4);
// StorageLive(_5);
// _11 = promoted[1];
// _5 = &'12ds (*_11);
// _4 = &'12ds (*_5);
// _10 = promoted[1];
// _4 = &'12ds (*_10);
// _3 = &'12ds (*_4);
// StorageLive(_6);
// StorageLive(_7);
// StorageLive(_8);
// _10 = promoted[0];
// _8 = &'10s (*_10);
// _7 = &'10s (*_8);
// _3 = D1<'12ds, '10s>::{{constructor}}(move _4, move _7);
// _9 = promoted[0];
// _7 = &'10s (*_9);
// _6 = &'10s (*_7);
// _2 = D1<'12ds, '10s>::{{constructor}}(move _3, move _6);
// EndRegion('10s);
// StorageDead(_7);
// StorageDead(_4);
// _2 = (_3.0: &'12ds S1);
// _1 = move _2;
// StorageDead(_2);
// drop(_3) -> [return: bb2, unwind: bb1];
// StorageDead(_6);
// StorageDead(_3);
// _1 = (_2.0: &'12ds S1);
// drop(_2) -> [return: bb2, unwind: bb1];
// }
//
// bb1: {
// resume;
// }
//
// bb2: {
// StorageDead(_3);
// StorageDead(_8);
// StorageDead(_5);
// StorageDead(_2);
// StorageDead(_7);
// StorageDead(_4);
// EndRegion('12ds);
// _0 = ();
// return;

View file

@ -38,11 +38,9 @@ fn foo<T: Copy>(_t: T, q: &i32) -> i32 {
// ...
// _7 = &(*_2);
// _5 = (move _6, move _7);
// _9 = move (_5.0: &i32);
// _10 = move (_5.1: &i32);
// StorageLive(_8);
// _8 = (*_9);
// _0 = move _8;
// _8 = move (_5.0: &i32);
// _9 = move (_5.1: &i32);
// _0 = (*_8);
// ...
// return;
// }

View file

@ -36,7 +36,7 @@ fn foo<T: Copy>(_t: T, q: i32) -> i32 {
// _5 = (move _6, move _7);
// _8 = move (_5.0: i32);
// _9 = move (_5.1: i32);
// _0 = move _8;
// _0 = _8;
// ...
// return;
// }

View file

@ -182,8 +182,8 @@ fn main() {
// ...
// _1 = move (_13.0: i128);
// ...
// _17 = const 7i32 as u128 (Misc);
// _14 = const compiler_builtins::int::shift::rust_i128_shro(_1, move _17) -> bb16;
// _16 = const 7i32 as u128 (Misc);
// _14 = const compiler_builtins::int::shift::rust_i128_shro(_1, move _16) -> bb16;
// ...
// _1 = move (_14.0: i128);
// ...
@ -195,8 +195,8 @@ fn main() {
// ...
// assert(!move (_13.1: bool), "attempt to shift left with overflow") -> bb8;
// ...
// _16 = const 6i32 as u128 (Misc);
// _13 = const compiler_builtins::int::shift::rust_i128_shlo(_1, move _16) -> bb14;
// _15 = const 6i32 as u128 (Misc);
// _13 = const compiler_builtins::int::shift::rust_i128_shlo(_1, move _15) -> bb14;
// ...
// assert(!move (_14.1: bool), "attempt to shift right with overflow") -> bb9;
// END rustc.test_signed.Lower128Bit.after.mir
@ -218,8 +218,8 @@ fn main() {
// ...
// _1 = move (_7.0: u128);
// ...
// _11 = const 7i32 as u128 (Misc);
// _8 = const compiler_builtins::int::shift::rust_u128_shro(_1, move _11) -> bb14;
// _10 = const 7i32 as u128 (Misc);
// _8 = const compiler_builtins::int::shift::rust_u128_shro(_1, move _10) -> bb14;
// ...
// _1 = move (_8.0: u128);
// ...
@ -231,8 +231,8 @@ fn main() {
// ...
// assert(!move (_7.1: bool), "attempt to shift left with overflow") -> bb6;
// ...
// _10 = const 6i32 as u128 (Misc);
// _7 = const compiler_builtins::int::shift::rust_u128_shlo(_1, move _10) -> bb12;
// _9 = const 6i32 as u128 (Misc);
// _7 = const compiler_builtins::int::shift::rust_u128_shlo(_1, move _9) -> bb12;
// ...
// assert(!move (_8.1: bool), "attempt to shift right with overflow") -> bb7;
// END rustc.test_unsigned.Lower128Bit.after.mir

View file

@ -176,11 +176,11 @@ fn main() {
// ...
// _1 = const compiler_builtins::int::addsub::rust_i128_sub(_1, const 2i128) -> bb6;
// ...
// _11 = const 7i32 as u32 (Misc);
// _1 = const compiler_builtins::int::shift::rust_i128_shr(_1, move _11) -> bb9;
// _10 = const 7i32 as u32 (Misc);
// _1 = const compiler_builtins::int::shift::rust_i128_shr(_1, move _10) -> bb9;
// ...
// _12 = const 6i32 as u32 (Misc);
// _1 = const compiler_builtins::int::shift::rust_i128_shl(_1, move _12) -> bb10;
// _11 = const 6i32 as u32 (Misc);
// _1 = const compiler_builtins::int::shift::rust_i128_shl(_1, move _11) -> bb10;
// END rustc.test_signed.Lower128Bit.after.mir
// START rustc.test_unsigned.Lower128Bit.after.mir
@ -194,9 +194,9 @@ fn main() {
// ...
// _1 = const compiler_builtins::int::addsub::rust_u128_sub(_1, const 2u128) -> bb4;
// ...
// _5 = const 7i32 as u32 (Misc);
// _1 = const compiler_builtins::int::shift::rust_u128_shr(_1, move _5) -> bb7;
// _4 = const 7i32 as u32 (Misc);
// _1 = const compiler_builtins::int::shift::rust_u128_shr(_1, move _4) -> bb7;
// ...
// _6 = const 6i32 as u32 (Misc);
// _1 = const compiler_builtins::int::shift::rust_u128_shl(_1, move _6) -> bb8;
// _5 = const 6i32 as u32 (Misc);
// _1 = const compiler_builtins::int::shift::rust_u128_shl(_1, move _5) -> bb8;
// END rustc.test_unsigned.Lower128Bit.after.mir

View file

@ -32,9 +32,9 @@ fn main() {
// END RUST SOURCE
// START rustc.main.nll.0.mir
// | '_#2r | {bb2[0..=6], bb3[0..=1]}
// | '_#3r | {bb2[1..=6], bb3[0..=1]}
// | '_#4r | {bb2[5..=6], bb3[0..=1]}
// | '_#2r | {bb2[0..=3], bb3[0..=1]}
// | '_#3r | {bb2[1..=3], bb3[0..=1]}
// | '_#4r | {bb2[3], bb3[0..=1]}
// END rustc.main.nll.0.mir
// START rustc.main.nll.0.mir
// let _6: &'_#4r usize;
@ -43,7 +43,5 @@ fn main() {
// ...
// _2 = &'_#2r _1[_3];
// ...
// _7 = _2;
// ...
// _6 = move _7;
// _6 = _2;
// END rustc.main.nll.0.mir

View file

@ -67,10 +67,7 @@ fn main() {
// Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 }))), [(*_2): i32]);
// _3 = &ReErased (*_2);
// Validate(Acquire, [(*_3): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 })) (imm)]);
// StorageLive(_4);
// _4 = (*_3);
// _0 = move _4;
// StorageDead(_4);
// _0 = (*_3);
// EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 })));
// StorageDead(_3);
// return;

View file

@ -1,9 +0,0 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508.rs:18:18
|
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
| ^^^^^^^^ cannot move out of here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0508`.

View file

@ -1,9 +0,0 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508.rs:18:18
|
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
| ^^^^^^^^ cannot move out of here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0508`.

View file

@ -8,13 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// revisions: ast mir
//[mir]compile-flags: -Z borrowck=mir
struct NonCopy;
fn main() {
let array = [NonCopy; 1];
let _value = array[0]; //[ast]~ ERROR [E0508]
//[mir]~^ ERROR [E0508]
let _value = array[0]; //~ ERROR [E0508]
}

View file

@ -1,7 +1,7 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508.rs:18:18
--> $DIR/E0508.rs:15:18
|
LL | let _value = array[0]; //[ast]~ ERROR [E0508]
LL | let _value = array[0]; //~ ERROR [E0508]
| ^^^^^^^^
| |
| cannot move out of here

View file

@ -1,40 +1,46 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-move-error-with-note.rs:23:19
--> $DIR/borrowck-move-error-with-note.rs:21:11
|
LL | match *f { //~ ERROR cannot move out of
| ^^
| |
| cannot move out of borrowed content
| help: consider removing this dereference operator: `f`
LL | //~| cannot move out
LL | Foo::Foo1(num1,
| ^^^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-move-error-with-note.rs:24:19
|
| ---- move occurs because num1 has type `std::boxed::Box<u32>`, which does not implement the `Copy` trait
LL | num2) => (),
| ^^^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-move-error-with-note.rs:25:19
|
| ---- move occurs because num2 has type `std::boxed::Box<u32>`, which does not implement the `Copy` trait
LL | Foo::Foo2(num) => (),
| ^^^ cannot move out of borrowed content
| --- move occurs because num has type `std::boxed::Box<u32>`, which does not implement the `Copy` trait
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-error-with-note.rs:42:16
--> $DIR/borrowck-move-error-with-note.rs:39:11
|
LL | f: _s,
| ^^ cannot move out of here
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-error-with-note.rs:43:16
LL | match (S {f: "foo".to_string(), g: "bar".to_string()}) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
help: to prevent move, use ref or ref mut
|
LL | g: _t
| ^^ cannot move out of here
LL | f: ref _s,
| ^^^^^^
help: to prevent move, use ref or ref mut
|
LL | g: ref _t
| ^^^^^^
error[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-move-error-with-note.rs:59:9
--> $DIR/borrowck-move-error-with-note.rs:57:11
|
LL | match a.a { //~ ERROR cannot move out of
| ^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&a.a`
LL | //~| cannot move out
LL | n => {
| ^ cannot move out of borrowed content
| - move occurs because n has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
error: aborting due to 6 previous errors
error: aborting due to 3 previous errors
Some errors occurred: E0507, E0509.
For more information about an error, try `rustc --explain E0507`.

View file

@ -1,15 +1,17 @@
error[E0508]: cannot move out of type `[Foo]`, a non-copy slice
--> $DIR/borrowck-move-out-of-vec-tail.rs:30:33
--> $DIR/borrowck-move-out-of-vec-tail.rs:29:19
|
LL | &[Foo { string: a },
| ^ cannot move out of here
error[E0508]: cannot move out of type `[Foo]`, a non-copy slice
--> $DIR/borrowck-move-out-of-vec-tail.rs:34:33
LL | match tail {
| ^^^^ cannot move out of here
help: to prevent move, use ref or ref mut
|
LL | Foo { string: b }] => {
| ^ cannot move out of here
LL | &[Foo { string: ref a },
| ^^^^^
help: to prevent move, use ref or ref mut
|
LL | Foo { string: ref b }] => {
| ^^^^^
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0508`.

View file

@ -23,54 +23,68 @@ LL | _b.use_ref();
| -- borrow later used here
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
--> $DIR/borrowck-vec-pattern-nesting.rs:44:15
--> $DIR/borrowck-vec-pattern-nesting.rs:43:11
|
LL | match vec {
| ^^^ cannot move out of here
LL | &mut [_a, //~ ERROR cannot move out
| ^^ cannot move out of here
| -- help: to prevent move, use ref or ref mut: `ref _a`
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
--> $DIR/borrowck-vec-pattern-nesting.rs:57:13
|
LL | let a = vec[0]; //~ ERROR cannot move out
| ^^^^^^ cannot move out of here
| ^^^^^^
| |
| cannot move out of here
| help: consider using a reference instead: `&vec[0]`
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
--> $DIR/borrowck-vec-pattern-nesting.rs:67:10
--> $DIR/borrowck-vec-pattern-nesting.rs:64:11
|
LL | match vec {
| ^^^ cannot move out of here
...
LL | _b] => {}
| ^^ cannot move out of here
| -- help: to prevent move, use ref or ref mut: `ref _b`
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
--> $DIR/borrowck-vec-pattern-nesting.rs:70:13
|
LL | let a = vec[0]; //~ ERROR cannot move out
| ^^^^^^ cannot move out of here
| ^^^^^^
| |
| cannot move out of here
| help: consider using a reference instead: `&vec[0]`
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
--> $DIR/borrowck-vec-pattern-nesting.rs:78:15
--> $DIR/borrowck-vec-pattern-nesting.rs:77:11
|
LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
| ^^ cannot move out of here
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
--> $DIR/borrowck-vec-pattern-nesting.rs:78:19
LL | match vec {
| ^^^ cannot move out of here
help: to prevent move, use ref or ref mut
|
LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
| ^^ cannot move out of here
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
--> $DIR/borrowck-vec-pattern-nesting.rs:78:23
LL | &mut [ref _a, _b, _c] => {} //~ ERROR cannot move out
| ^^^^^^
help: to prevent move, use ref or ref mut
|
LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
| ^^ cannot move out of here
LL | &mut [_a, ref _b, _c] => {} //~ ERROR cannot move out
| ^^^^^^
help: to prevent move, use ref or ref mut
|
LL | &mut [_a, _b, ref _c] => {} //~ ERROR cannot move out
| ^^^^^^
error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
--> $DIR/borrowck-vec-pattern-nesting.rs:82:13
|
LL | let a = vec[0]; //~ ERROR cannot move out
| ^^^^^^ cannot move out of here
| ^^^^^^
| |
| cannot move out of here
| help: consider using a reference instead: `&vec[0]`
error: aborting due to 10 previous errors
error: aborting due to 8 previous errors
Some errors occurred: E0506, E0508.
For more information about an error, try `rustc --explain E0506`.

View file

@ -1,8 +1,11 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/issue-51415.rs:16:47
--> $DIR/issue-51415.rs:16:42
|
LL | let opt = a.iter().enumerate().find(|(_, &s)| {
| ^ cannot move out of borrowed content
| ^^^^^-^
| | |
| | help: to prevent move, use ref or ref mut: `ref s`
| cannot move out of borrowed content
error: aborting due to previous error

View file

@ -1,8 +1,10 @@
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/overlapping_spans.rs:21:14
--> $DIR/overlapping_spans.rs:20:11
|
LL | match (S {f:"foo".to_string()}) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
LL | S {f:_s} => {} //~ ERROR cannot move out
| ^^ cannot move out of here
| -- help: to prevent move, use ref or ref mut: `ref _s`
error: aborting due to previous error

View file

@ -1,9 +0,0 @@
error[E0509]: cannot move out of type `DropStruct`, which implements the `Drop` trait
--> $DIR/E0509.rs:26:23
|
LL | let fancy_field = drop_struct.fancy; //~ ERROR E0509
| ^^^^^^^^^^^^^^^^^ cannot move out of here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0509`.

View file

@ -2,7 +2,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/issue-40402-1.rs:19:13
|
LL | let e = f.v[0]; //~ ERROR cannot move out of indexed content
| ^^^^^^ cannot move out of borrowed content
| ^^^^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&f.v[0]`
error: aborting due to previous error

View file

@ -1,15 +1,14 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/issue-40402-2.rs:15:10
--> $DIR/issue-40402-2.rs:15:18
|
LL | let (a, b) = x[0]; //~ ERROR cannot move out of indexed content
| ^ cannot move out of borrowed content
| - - ^^^^
| | | |
| | | cannot move out of borrowed content
| | | help: consider using a reference instead: `&x[0]`
| | move occurs because b has type `std::string::String`, which does not implement the `Copy` trait
| move occurs because a has type `std::string::String`, which does not implement the `Copy` trait
error[E0507]: cannot move out of borrowed content
--> $DIR/issue-40402-2.rs:15:13
|
LL | let (a, b) = x[0]; //~ ERROR cannot move out of indexed content
| ^ cannot move out of borrowed content
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.

View file

@ -1,8 +1,14 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/moves-based-on-type-block-bad.rs:37:28
--> $DIR/moves-based-on-type-block-bad.rs:34:19
|
LL | match hellothere.x { //~ ERROR cannot move out
| ^^^^^^^^^^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&hellothere.x`
...
LL | box E::Bar(x) => println!("{}", x.to_string()),
| ^ cannot move out of borrowed content
| - move occurs because x has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
error: aborting due to previous error

View file

@ -0,0 +1,130 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(unused)]
#![feature(nll)]
struct A(String);
struct C(D);
fn suggest_remove_deref() {
let a = &A("".to_string());
let b = *a;
//~^ ERROR
}
fn suggest_borrow() {
let a = [A("".to_string())];
let b = a[0];
//~^ ERROR
}
fn suggest_borrow2() {
let mut a = A("".to_string());
let r = &&mut a;
let s = **r;
//~^ ERROR
}
fn suggest_borrow3() {
use std::rc::Rc;
let mut a = A("".to_string());
let r = Rc::new(a);
let s = *r;
//~^ ERROR
}
fn suggest_borrow4() {
let a = [A("".to_string())][0];
//~^ ERROR
}
fn suggest_borrow5() {
let a = &A("".to_string());
let A(s) = *a;
//~^ ERROR
}
fn suggest_ref() {
let c = C(D(String::new()));
let C(D(s)) = c;
//~^ ERROR
}
fn suggest_nothing() {
let a = &A("".to_string());
let b;
b = *a;
//~^ ERROR
}
enum B {
V(String),
U(D),
}
struct D(String);
impl Drop for D {
fn drop(&mut self) {}
}
struct F(String, String);
impl Drop for F {
fn drop(&mut self) {}
}
fn probably_suggest_borrow() {
let x = [B::V(String::new())];
match x[0] {
//~^ ERROR
B::U(d) => (),
B::V(s) => (),
}
}
fn have_to_suggest_ref() {
let x = B::V(String::new());
match x {
//~^ ERROR
B::V(s) => drop(s),
B::U(D(s)) => (),
};
}
fn two_separate_errors() {
let x = (D(String::new()), &String::new());
match x {
//~^ ERROR
//~^^ ERROR
(D(s), &t) => (),
_ => (),
}
}
fn have_to_suggest_double_ref() {
let x = F(String::new(), String::new());
match x {
//~^ ERROR
F(s, mut t) => (),
_ => (),
}
}
fn double_binding(x: &Result<String, String>) {
match *x {
//~^ ERROR
Ok(s) | Err(s) => (),
}
}
fn main() {
}

View file

@ -0,0 +1,140 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/move-errors.rs:19:13
|
LL | let b = *a;
| ^^
| |
| cannot move out of borrowed content
| help: consider removing this dereference operator: `a`
error[E0508]: cannot move out of type `[A; 1]`, a non-copy array
--> $DIR/move-errors.rs:25:13
|
LL | let b = a[0];
| ^^^^
| |
| cannot move out of here
| help: consider using a reference instead: `&a[0]`
error[E0507]: cannot move out of borrowed content
--> $DIR/move-errors.rs:32:13
|
LL | let s = **r;
| ^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&**r`
error[E0507]: cannot move out of borrowed content
--> $DIR/move-errors.rs:40:13
|
LL | let s = *r;
| ^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&*r`
error[E0508]: cannot move out of type `[A; 1]`, a non-copy array
--> $DIR/move-errors.rs:45:13
|
LL | let a = [A("".to_string())][0];
| ^^^^^^^^^^^^^^^^^^^^^^
| |
| cannot move out of here
| help: consider using a reference instead: `&[A("".to_string())][0]`
error[E0507]: cannot move out of borrowed content
--> $DIR/move-errors.rs:51:16
|
LL | let A(s) = *a;
| - ^^
| | |
| | cannot move out of borrowed content
| | help: consider removing this dereference operator: `a`
| move occurs because s has type `std::string::String`, which does not implement the `Copy` trait
error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
--> $DIR/move-errors.rs:57:19
|
LL | let C(D(s)) = c;
| - ^ cannot move out of here
| |
| help: to prevent move, use ref or ref mut: `ref s`
error[E0507]: cannot move out of borrowed content
--> $DIR/move-errors.rs:64:9
|
LL | b = *a;
| ^^ cannot move out of borrowed content
error[E0508]: cannot move out of type `[B; 1]`, a non-copy array
--> $DIR/move-errors.rs:87:11
|
LL | match x[0] {
| ^^^^
| |
| cannot move out of here
| help: consider using a reference instead: `&x[0]`
LL | //~^ ERROR
LL | B::U(d) => (),
| - move occurs because d has type `D`, which does not implement the `Copy` trait
LL | B::V(s) => (),
| - move occurs because s has type `std::string::String`, which does not implement the `Copy` trait
error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
--> $DIR/move-errors.rs:96:11
|
LL | match x {
| ^ cannot move out of here
...
LL | B::U(D(s)) => (),
| - help: to prevent move, use ref or ref mut: `ref s`
error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
--> $DIR/move-errors.rs:105:11
|
LL | match x {
| ^ cannot move out of here
...
LL | (D(s), &t) => (),
| - help: to prevent move, use ref or ref mut: `ref s`
error[E0507]: cannot move out of borrowed content
--> $DIR/move-errors.rs:105:11
|
LL | match x {
| ^ cannot move out of borrowed content
...
LL | (D(s), &t) => (),
| - help: to prevent move, use ref or ref mut: `ref t`
error[E0509]: cannot move out of type `F`, which implements the `Drop` trait
--> $DIR/move-errors.rs:115:11
|
LL | match x {
| ^ cannot move out of here
help: to prevent move, use ref or ref mut
|
LL | F(ref s, mut t) => (),
| ^^^^^
help: to prevent move, use ref or ref mut
|
LL | F(s, ref mut t) => (),
| ^^^^^^^^^
error[E0507]: cannot move out of borrowed content
--> $DIR/move-errors.rs:123:11
|
LL | match *x {
| ^^
| |
| cannot move out of borrowed content
| help: consider removing this dereference operator: `x`
LL | //~^ ERROR
LL | Ok(s) | Err(s) => (),
| - move occurs because s has type `std::string::String`, which does not implement the `Copy` trait
error: aborting due to 14 previous errors
Some errors occurred: E0507, E0508, E0509.
For more information about an error, try `rustc --explain E0507`.