Fix move errors for index expressions

The suggestion logic gave up too early, which kept it from suggesting
borrowing index expressions.
This commit is contained in:
ashtneoi 2018-08-07 23:44:35 -07:00
parent 54ddb36ce7
commit 8080bdf275
2 changed files with 64 additions and 43 deletions

View File

@ -341,38 +341,32 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
move_from, move_from,
.. ..
} => { } => {
let mut suggest_change_head_expr = false; let try_remove_deref = match move_from {
match move_from {
Place::Projection(box PlaceProjection { Place::Projection(box PlaceProjection {
elem: ProjectionElem::Deref, elem: ProjectionElem::Deref,
.. ..
}) => { }) => true,
_ => false,
};
if try_remove_deref && snippet.starts_with('*') {
// This is false for (e.g.) index expressions `a[b]`, // This is false for (e.g.) index expressions `a[b]`,
// which roughly desugar to `*Index::index(&a, b)` or // which roughly desugar to `*Index::index(&a, b)` or
// `*IndexMut::index_mut(&mut a, b)`. // `*IndexMut::index_mut(&mut a, b)`.
if snippet.starts_with('*') {
err.span_suggestion( err.span_suggestion(
span, span,
"consider removing this dereference operator", "consider removing this dereference operator",
(&snippet[1..]).to_owned(), snippet[1..].to_owned(),
); );
suggest_change_head_expr = true; } else {
}
}
_ => {
err.span_suggestion( err.span_suggestion(
span, span,
"consider using a reference instead", "consider using a reference instead",
format!("&{}", snippet), format!("&{}", snippet),
); );
suggest_change_head_expr = true;
}
} }
binds_to.sort(); binds_to.sort();
binds_to.dedup(); binds_to.dedup();
if !suggest_change_head_expr {
self.add_move_error_suggestions(err, &binds_to);
}
self.add_move_error_labels(err, &binds_to); self.add_move_error_labels(err, &binds_to);
} }
GroupedMoveError::MovesFromValue { mut binds_to, .. } => { GroupedMoveError::MovesFromValue { mut binds_to, .. } => {

View File

@ -188,8 +188,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:111:17 --> $DIR/dont-suggest-ref.rs:111:17
| |
LL | let X(_t) = vs_[0]; LL | let X(_t) = vs_[0];
| -- ^^^^^^ cannot move out of borrowed content | -- ^^^^^^
| | | | |
| | cannot move out of borrowed content
| | help: consider using a reference instead: `&vs_[0]`
| data moved here | data moved here
| |
note: move occurs because _t has type `Y`, which does not implement the `Copy` trait note: move occurs because _t has type `Y`, which does not implement the `Copy` trait
@ -202,8 +204,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:115:30 --> $DIR/dont-suggest-ref.rs:115:30
| |
LL | if let Either::One(_t) = vr[0] { } LL | if let Either::One(_t) = vr[0] { }
| -- ^^^^^ cannot move out of borrowed content | -- ^^^^^
| | | | |
| | cannot move out of borrowed content
| | help: consider using a reference instead: `&vr[0]`
| data moved here | data moved here
| |
note: move occurs because _t has type `X`, which does not implement the `Copy` trait note: move occurs because _t has type `X`, which does not implement the `Copy` trait
@ -216,8 +220,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:119:33 --> $DIR/dont-suggest-ref.rs:119:33
| |
LL | while let Either::One(_t) = vr[0] { } LL | while let Either::One(_t) = vr[0] { }
| -- ^^^^^ cannot move out of borrowed content | -- ^^^^^
| | | | |
| | cannot move out of borrowed content
| | help: consider using a reference instead: `&vr[0]`
| data moved here | data moved here
| |
note: move occurs because _t has type `X`, which does not implement the `Copy` trait note: move occurs because _t has type `X`, which does not implement the `Copy` trait
@ -230,7 +236,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:123:11 --> $DIR/dont-suggest-ref.rs:123:11
| |
LL | match vr[0] { LL | match vr[0] {
| ^^^^^ cannot move out of borrowed content | ^^^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&vr[0]`
... ...
LL | Either::One(_t) LL | Either::One(_t)
| -- data moved here | -- data moved here
@ -245,7 +254,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:130:11 --> $DIR/dont-suggest-ref.rs:130:11
| |
LL | match vr[0] { LL | match vr[0] {
| ^^^^^ cannot move out of borrowed content | ^^^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&vr[0]`
... ...
LL | Either::One(_t) => (), LL | Either::One(_t) => (),
| -- data moved here | -- data moved here
@ -260,8 +272,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:139:17 --> $DIR/dont-suggest-ref.rs:139:17
| |
LL | let X(_t) = vsm[0]; LL | let X(_t) = vsm[0];
| -- ^^^^^^ cannot move out of borrowed content | -- ^^^^^^
| | | | |
| | cannot move out of borrowed content
| | help: consider using a reference instead: `&vsm[0]`
| data moved here | data moved here
| |
note: move occurs because _t has type `Y`, which does not implement the `Copy` trait note: move occurs because _t has type `Y`, which does not implement the `Copy` trait
@ -274,8 +288,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:143:30 --> $DIR/dont-suggest-ref.rs:143:30
| |
LL | if let Either::One(_t) = vrm[0] { } LL | if let Either::One(_t) = vrm[0] { }
| -- ^^^^^^ cannot move out of borrowed content | -- ^^^^^^
| | | | |
| | cannot move out of borrowed content
| | help: consider using a reference instead: `&vrm[0]`
| data moved here | data moved here
| |
note: move occurs because _t has type `X`, which does not implement the `Copy` trait note: move occurs because _t has type `X`, which does not implement the `Copy` trait
@ -288,8 +304,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:147:33 --> $DIR/dont-suggest-ref.rs:147:33
| |
LL | while let Either::One(_t) = vrm[0] { } LL | while let Either::One(_t) = vrm[0] { }
| -- ^^^^^^ cannot move out of borrowed content | -- ^^^^^^
| | | | |
| | cannot move out of borrowed content
| | help: consider using a reference instead: `&vrm[0]`
| data moved here | data moved here
| |
note: move occurs because _t has type `X`, which does not implement the `Copy` trait note: move occurs because _t has type `X`, which does not implement the `Copy` trait
@ -302,7 +320,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:151:11 --> $DIR/dont-suggest-ref.rs:151:11
| |
LL | match vrm[0] { LL | match vrm[0] {
| ^^^^^^ cannot move out of borrowed content | ^^^^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&vrm[0]`
... ...
LL | Either::One(_t) LL | Either::One(_t)
| -- data moved here | -- data moved here
@ -317,7 +338,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:158:11 --> $DIR/dont-suggest-ref.rs:158:11
| |
LL | match vrm[0] { LL | match vrm[0] {
| ^^^^^^ cannot move out of borrowed content | ^^^^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&vrm[0]`
... ...
LL | Either::One(_t) => (), LL | Either::One(_t) => (),
| -- data moved here | -- data moved here
@ -332,7 +356,10 @@ error[E0507]: cannot move out of borrowed content
--> $DIR/dont-suggest-ref.rs:166:11 --> $DIR/dont-suggest-ref.rs:166:11
| |
LL | match vrm[0] { LL | match vrm[0] {
| ^^^^^^ cannot move out of borrowed content | ^^^^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&vrm[0]`
... ...
LL | Either::One(_t) => (), LL | Either::One(_t) => (),
| -- data moved here | -- data moved here