Skip to content

Commit 49d4359

Browse files
authored
Rollup merge of rust-lang#54269 - PramodBisht:issue/53840, r=estebank
rust-lang#53840: Consolidate pattern check errors rust-lang#53840 on this PR we are aggregating `cannot bind by-move and by-ref in the same pattern` message present on the different lines into one diagnostic message. Here we are first gathering those `spans` on `vector` then we are throwing them with the help of `MultiSpan` r? @estebank Addresses: rust-lang#53480
2 parents 1c5e9c6 + e536e64 commit 49d4359

File tree

3 files changed

+67
-14
lines changed

3 files changed

+67
-14
lines changed

src/librustc_mir/hair/pattern/check_match.rs

+20-14
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use std::slice;
3535

3636
use syntax::ast;
3737
use syntax::ptr::P;
38-
use syntax_pos::{Span, DUMMY_SP};
38+
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
3939

4040
struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
4141

@@ -527,8 +527,8 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
527527
}
528528
})
529529
}
530-
531-
let check_move = |p: &Pat, sub: Option<&Pat>| {
530+
let span_vec = &mut Vec::new();
531+
let check_move = |p: &Pat, sub: Option<&Pat>, span_vec: &mut Vec<Span>| {
532532
// check legality of moving out of the enum
533533

534534
// x @ Foo(..) is legal, but x @ Foo(y) isn't.
@@ -546,16 +546,8 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
546546
crate attributes to enable");
547547
}
548548
err.emit();
549-
} else if let Some(by_ref_span) = by_ref_span {
550-
struct_span_err!(
551-
cx.tcx.sess,
552-
p.span,
553-
E0009,
554-
"cannot bind by-move and by-ref in the same pattern",
555-
)
556-
.span_label(p.span, "by-move pattern here")
557-
.span_label(by_ref_span, "both by-ref and by-move used")
558-
.emit();
549+
} else if let Some(_by_ref_span) = by_ref_span {
550+
span_vec.push(p.span);
559551
}
560552
};
561553

@@ -567,7 +559,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
567559
ty::BindByValue(..) => {
568560
let pat_ty = cx.tables.node_id_to_type(p.hir_id);
569561
if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) {
570-
check_move(p, sub.as_ref().map(|p| &**p));
562+
check_move(p, sub.as_ref().map(|p| &**p), span_vec);
571563
}
572564
}
573565
_ => {}
@@ -579,6 +571,20 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
579571
true
580572
});
581573
}
574+
if !span_vec.is_empty(){
575+
let span = MultiSpan::from_spans(span_vec.clone());
576+
let mut err = struct_span_err!(
577+
cx.tcx.sess,
578+
span,
579+
E0009,
580+
"cannot bind by-move and by-ref in the same pattern",
581+
);
582+
err.span_label(by_ref_span.unwrap(), "both by-ref and by-move used");
583+
for span in span_vec.iter(){
584+
err.span_label(*span, "by-move pattern here");
585+
}
586+
err.emit();
587+
}
582588
}
583589

584590
/// Ensures that a pattern guard doesn't borrow by mutable reference or

src/test/ui/issue-53840.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
enum E {
11+
Foo(String, String, String),
12+
}
13+
14+
struct Bar {
15+
a: String,
16+
b: String,
17+
}
18+
19+
fn main() {
20+
let bar = Bar { a: "1".to_string(), b: "2".to_string() };
21+
match E::Foo("".into(), "".into(), "".into()) {
22+
E::Foo(a, b, ref c) => {}
23+
}
24+
match bar {
25+
Bar {a, ref b} => {}
26+
}
27+
}

src/test/ui/issue-53840.stderr

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0009]: cannot bind by-move and by-ref in the same pattern
2+
--> $DIR/issue-53840.rs:22:16
3+
|
4+
LL | E::Foo(a, b, ref c) => {}
5+
| ^ ^ ----- both by-ref and by-move used
6+
| | |
7+
| | by-move pattern here
8+
| by-move pattern here
9+
10+
error[E0009]: cannot bind by-move and by-ref in the same pattern
11+
--> $DIR/issue-53840.rs:25:14
12+
|
13+
LL | Bar {a, ref b} => {}
14+
| ^ ----- both by-ref and by-move used
15+
| |
16+
| by-move pattern here
17+
18+
error: aborting due to 2 previous errors
19+
20+
For more information about this error, try `rustc --explain E0009`.

0 commit comments

Comments
 (0)