From 8080bdf275e7c12b8629c3b598c6ab18748957ee Mon Sep 17 00:00:00 2001 From: ashtneoi Date: Tue, 7 Aug 2018 23:44:35 -0700 Subject: [PATCH] Fix move errors for index expressions The suggestion logic gave up too early, which kept it from suggesting borrowing index expressions. --- src/librustc_mir/borrow_check/move_errors.rs | 46 ++++++-------- .../ui/suggestions/dont-suggest-ref.stderr | 61 +++++++++++++------ 2 files changed, 64 insertions(+), 43 deletions(-) diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index c641e960ac5..961d8eb7b94 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -341,38 +341,32 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { move_from, .. } => { - let mut suggest_change_head_expr = false; - match move_from { + let try_remove_deref = match move_from { Place::Projection(box PlaceProjection { elem: ProjectionElem::Deref, .. - }) => { - // This is false for (e.g.) index expressions `a[b]`, - // which roughly desugar to `*Index::index(&a, b)` or - // `*IndexMut::index_mut(&mut a, b)`. - if snippet.starts_with('*') { - err.span_suggestion( - span, - "consider removing this dereference operator", - (&snippet[1..]).to_owned(), - ); - suggest_change_head_expr = true; - } - } - _ => { - err.span_suggestion( - span, - "consider using a reference instead", - format!("&{}", snippet), - ); - suggest_change_head_expr = true; - } + }) => true, + _ => false, + }; + if try_remove_deref && snippet.starts_with('*') { + // This is false for (e.g.) index expressions `a[b]`, + // which roughly desugar to `*Index::index(&a, b)` or + // `*IndexMut::index_mut(&mut a, b)`. + err.span_suggestion( + span, + "consider removing this dereference operator", + snippet[1..].to_owned(), + ); + } else { + err.span_suggestion( + span, + "consider using a reference instead", + format!("&{}", snippet), + ); } + binds_to.sort(); binds_to.dedup(); - if !suggest_change_head_expr { - self.add_move_error_suggestions(err, &binds_to); - } self.add_move_error_labels(err, &binds_to); } GroupedMoveError::MovesFromValue { mut binds_to, .. } => { diff --git a/src/test/ui/suggestions/dont-suggest-ref.stderr b/src/test/ui/suggestions/dont-suggest-ref.stderr index d27c028fe47..16f11f9b10a 100644 --- a/src/test/ui/suggestions/dont-suggest-ref.stderr +++ b/src/test/ui/suggestions/dont-suggest-ref.stderr @@ -188,8 +188,10 @@ error[E0507]: cannot move out of borrowed content --> $DIR/dont-suggest-ref.rs:111:17 | 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 | 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 | 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 | 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 | 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 | 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 | 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) | -- data moved here @@ -245,7 +254,10 @@ error[E0507]: cannot move out of borrowed content --> $DIR/dont-suggest-ref.rs:130:11 | 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) => (), | -- data moved here @@ -260,8 +272,10 @@ error[E0507]: cannot move out of borrowed content --> $DIR/dont-suggest-ref.rs:139:17 | 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 | 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 | 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 | 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 | 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 | 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 | 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) | -- data moved here @@ -317,7 +338,10 @@ error[E0507]: cannot move out of borrowed content --> $DIR/dont-suggest-ref.rs:158:11 | 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) => (), | -- data moved here @@ -332,7 +356,10 @@ error[E0507]: cannot move out of borrowed content --> $DIR/dont-suggest-ref.rs:166:11 | 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) => (), | -- data moved here