1
Fork 0

check_legality_of_move_bindings: generalize diagnostics & add comments

This commit is contained in:
Mazdak Farrokhzad 2019-12-14 18:20:13 +01:00
parent 25b6a28a51
commit 6a87f99620
12 changed files with 33 additions and 30 deletions

View file

@ -579,18 +579,20 @@ fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[super::Pat<'_>]) -> Vec<Span>
// Check the legality of legality of by-move bindings. // Check the legality of legality of by-move bindings.
fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat) { fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: bool, pat: &Pat) {
let mut by_ref_span = None; // Find all by-ref spans.
let mut by_ref_spans = Vec::new();
pat.each_binding(|_, hir_id, span, _| { pat.each_binding(|_, hir_id, span, _| {
if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) { if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) {
if let ty::BindByReference(..) = bm { if let ty::BindByReference(..) = bm {
by_ref_span = Some(span); by_ref_spans.push(span);
} }
} else { } else {
cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
} }
}); });
let span_vec = &mut Vec::new(); // Find bad by-move spans:
let by_move_spans = &mut Vec::new();
let mut check_move = |p: &Pat, sub: Option<&Pat>| { let mut check_move = |p: &Pat, sub: Option<&Pat>| {
// Check legality of moving out of the enum. // Check legality of moving out of the enum.
// //
@ -599,11 +601,10 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
struct_span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings") struct_span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings")
.span_label(p.span, "binds an already bound by-move value by moving it") .span_label(p.span, "binds an already bound by-move value by moving it")
.emit(); .emit();
} else if !has_guard && by_ref_span.is_some() { } else if !has_guard && !by_ref_spans.is_empty() {
span_vec.push(p.span); by_move_spans.push(p.span);
} }
}; };
pat.walk(|p| { pat.walk(|p| {
if let hir::PatKind::Binding(.., sub) = &p.kind { if let hir::PatKind::Binding(.., sub) = &p.kind {
if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
@ -620,17 +621,18 @@ fn check_legality_of_move_bindings(cx: &mut MatchVisitor<'_, '_>, has_guard: boo
true true
}); });
if !span_vec.is_empty() { // Found some bad by-move spans, error!
if !by_move_spans.is_empty() {
let mut err = struct_span_err!( let mut err = struct_span_err!(
cx.tcx.sess, cx.tcx.sess,
MultiSpan::from_spans(span_vec.clone()), MultiSpan::from_spans(by_move_spans.clone()),
E0009, E0009,
"cannot bind by-move and by-ref in the same pattern", "cannot bind by-move and by-ref in the same pattern",
); );
if let Some(by_ref_span) = by_ref_span { for span in by_ref_spans.iter() {
err.span_label(by_ref_span, "both by-ref and by-move used"); err.span_label(*span, "by-ref pattern here");
} }
for span in span_vec.iter() { for span in by_move_spans.iter() {
err.span_label(*span, "by-move pattern here"); err.span_label(*span, "by-move pattern here");
} }
err.emit(); err.emit();

View file

@ -4,7 +4,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern
LL | Some((ref _y, _z)) => { }, LL | Some((ref _y, _z)) => { },
| ------ ^^ by-move pattern here | ------ ^^ by-move pattern here
| | | |
| both by-ref and by-move used | by-ref pattern here
error: aborting due to previous error error: aborting due to previous error

View file

@ -4,7 +4,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern
LL | DoubleOption::Some2(ref _y, _z) => { }, LL | DoubleOption::Some2(ref _y, _z) => { },
| ------ ^^ by-move pattern here | ------ ^^ by-move pattern here
| | | |
| both by-ref and by-move used | by-ref pattern here
error: aborting due to previous error error: aborting due to previous error

View file

@ -2,7 +2,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-4.rs:12:15 --> $DIR/bind-by-move-neither-can-live-while-the-other-survives-4.rs:12:15
| |
LL | Some((_y, ref _z)) => { }, LL | Some((_y, ref _z)) => { },
| ^^ ------ both by-ref and by-move used | ^^ ------ by-ref pattern here
| | | |
| by-move pattern here | by-move pattern here

View file

@ -2,7 +2,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/E0009.rs:5:15 --> $DIR/E0009.rs:5:15
| |
LL | Some((y, ref z)) => {}, LL | Some((y, ref z)) => {},
| ^ ----- both by-ref and by-move used | ^ ----- by-ref pattern here
| | | |
| by-move pattern here | by-move pattern here

View file

@ -2,7 +2,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/issue-53840.rs:13:16 --> $DIR/issue-53840.rs:13:16
| |
LL | E::Foo(a, b, ref c) => {} LL | E::Foo(a, b, ref c) => {}
| ^ ^ ----- both by-ref and by-move used | ^ ^ ----- by-ref pattern here
| | | | | |
| | by-move pattern here | | by-move pattern here
| by-move pattern here | by-move pattern here
@ -11,7 +11,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/issue-53840.rs:17:14 --> $DIR/issue-53840.rs:17:14
| |
LL | Bar {a, ref b} => {} LL | Bar {a, ref b} => {}
| ^ ----- both by-ref and by-move used | ^ ----- by-ref pattern here
| | | |
| by-move pattern here | by-move pattern here

View file

@ -13,7 +13,7 @@ LL | Some(ref _y @ _z) => { },
| ---------^^ | ---------^^
| | | | | |
| | by-move pattern here | | by-move pattern here
| both by-ref and by-move used | by-ref pattern here
error: aborting due to previous error error: aborting due to previous error

View file

@ -25,7 +25,7 @@ LL | let ref a @ box b = Box::new(NC);
| ------------^ | ------------^
| | | | | |
| | by-move pattern here | | by-move pattern here
| both by-ref and by-move used | by-ref pattern here
error[E0382]: use of moved value error[E0382]: use of moved value
--> $DIR/borrowck-pat-at-and-box.rs:11:18 --> $DIR/borrowck-pat-at-and-box.rs:11:18

View file

@ -13,7 +13,7 @@ LL | ref op_string_ref @ Some(s) => {},
| -------------------------^- | -------------------------^-
| | | | | |
| | by-move pattern here | | by-move pattern here
| both by-ref and by-move used | by-ref pattern here
error: aborting due to previous error error: aborting due to previous error

View file

@ -124,5 +124,5 @@ LL | drop(a);
error: aborting due to 11 previous errors error: aborting due to 11 previous errors
Some errors have detailed explanations: E0502, E0507. Some errors have detailed explanations: E0502, E0507, E0594.
For more information about an error, try `rustc --explain E0502`. For more information about an error, try `rustc --explain E0502`.

View file

@ -13,7 +13,7 @@ LL | let ref a @ b = NotCopy;
| --------^ | --------^
| | | | | |
| | by-move pattern here | | by-move pattern here
| both by-ref and by-move used | by-ref pattern here
error[E0009]: cannot bind by-move and by-ref in the same pattern error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/default-binding-modes-both-sides-independent.rs:22:21 --> $DIR/default-binding-modes-both-sides-independent.rs:22:21
@ -22,17 +22,18 @@ LL | let ref mut a @ b = NotCopy;
| ------------^ | ------------^
| | | | | |
| | by-move pattern here | | by-move pattern here
| both by-ref and by-move used | by-ref pattern here
error[E0009]: cannot bind by-move and by-ref in the same pattern error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/default-binding-modes-both-sides-independent.rs:24:20 --> $DIR/default-binding-modes-both-sides-independent.rs:24:20
| |
LL | Ok(ref a @ b) | Err(ref a @ b) => {} LL | Ok(ref a @ b) | Err(ref a @ b) => {}
| ^ --------^ | --------^ --------^
| | | | | | | | |
| | | by-move pattern here | | | | by-move pattern here
| | both by-ref and by-move used | | | by-ref pattern here
| by-move pattern here | | by-move pattern here
| by-ref pattern here
error[E0009]: cannot bind by-move and by-ref in the same pattern error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/default-binding-modes-both-sides-independent.rs:28:17 --> $DIR/default-binding-modes-both-sides-independent.rs:28:17
@ -41,7 +42,7 @@ LL | ref a @ b => {}
| --------^ | --------^
| | | | | |
| | by-move pattern here | | by-move pattern here
| both by-ref and by-move used | by-ref pattern here
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -4,7 +4,7 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern
LL | for (n, mut m) in &tups { LL | for (n, mut m) in &tups {
| - ^^^^^ by-move pattern here | - ^^^^^ by-move pattern here
| | | |
| both by-ref and by-move used | by-ref pattern here
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/for.rs:6:23 --> $DIR/for.rs:6:23