// Check the legality of legality of by-move bindings.
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, _| {
if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) {
if let ty::BindByReference(..) = bm {
- by_ref_span = Some(span);
+ by_ref_spans.push(span);
}
} else {
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>| {
// Check legality of moving out of the enum.
//
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")
.emit();
- } else if !has_guard && by_ref_span.is_some() {
- span_vec.push(p.span);
+ } else if !has_guard && !by_ref_spans.is_empty() {
+ by_move_spans.push(p.span);
}
};
-
pat.walk(|p| {
if let hir::PatKind::Binding(.., sub) = &p.kind {
if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
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!(
cx.tcx.sess,
- MultiSpan::from_spans(span_vec.clone()),
+ MultiSpan::from_spans(by_move_spans.clone()),
E0009,
"cannot bind by-move and by-ref in the same pattern",
);
- if let Some(by_ref_span) = by_ref_span {
- err.span_label(by_ref_span, "both by-ref and by-move used");
+ for span in by_ref_spans.iter() {
+ 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.emit();
--> $DIR/issue-53840.rs:13:16
|
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
--> $DIR/issue-53840.rs:17:14
|
LL | Bar {a, ref b} => {}
- | ^ ----- both by-ref and by-move used
+ | ^ ----- by-ref pattern here
| |
| 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
--> $DIR/default-binding-modes-both-sides-independent.rs:22:21
| ------------^
| | |
| | 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
--> $DIR/default-binding-modes-both-sides-independent.rs:24:20
|
LL | Ok(ref a @ b) | Err(ref a @ b) => {}
- | ^ --------^
- | | | |
- | | | by-move pattern here
- | | both by-ref and by-move used
- | by-move pattern here
+ | --------^ --------^
+ | | | | |
+ | | | | by-move pattern here
+ | | | by-ref pattern here
+ | | by-move pattern here
+ | by-ref pattern here
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/default-binding-modes-both-sides-independent.rs:28:17
| --------^
| | |
| | by-move pattern here
- | both by-ref and by-move used
+ | by-ref pattern here
error: aborting due to 4 previous errors