diff options
| author | Pietro Albini <pietro@pietroalbini.org> | 2018-10-02 22:54:27 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-10-02 22:54:27 +0200 |
| commit | 49d4359f6df32663e220d1ba6a3ccfe345ba2979 (patch) | |
| tree | 42d01dcafa3a5e35eebb5c4aa9122d686f7c08ad | |
| parent | 1c5e9c68ea6c76fe400528de17ebe03e338bac68 (diff) | |
| parent | e536e64702a12898ba7156c66de40b652ac21db1 (diff) | |
| download | rust-49d4359f6df32663e220d1ba6a3ccfe345ba2979.tar.gz rust-49d4359f6df32663e220d1ba6a3ccfe345ba2979.zip | |
Rollup merge of #54269 - PramodBisht:issue/53840, r=estebank
#53840: Consolidate pattern check errors #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: #53480
| -rw-r--r-- | src/librustc_mir/hair/pattern/check_match.rs | 34 | ||||
| -rw-r--r-- | src/test/ui/issue-53840.rs | 27 | ||||
| -rw-r--r-- | src/test/ui/issue-53840.stderr | 20 |
3 files changed, 67 insertions, 14 deletions
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 6187e091319..f2ae5774da8 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -35,7 +35,7 @@ use std::slice; use syntax::ast; use syntax::ptr::P; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::{Span, DUMMY_SP, MultiSpan}; struct OuterVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } @@ -527,8 +527,8 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, } }) } - - let check_move = |p: &Pat, sub: Option<&Pat>| { + let span_vec = &mut Vec::new(); + let check_move = |p: &Pat, sub: Option<&Pat>, span_vec: &mut Vec<Span>| { // check legality of moving out of the enum // x @ Foo(..) is legal, but x @ Foo(y) isn't. @@ -546,16 +546,8 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, crate attributes to enable"); } err.emit(); - } else if let Some(by_ref_span) = by_ref_span { - struct_span_err!( - cx.tcx.sess, - p.span, - E0009, - "cannot bind by-move and by-ref in the same pattern", - ) - .span_label(p.span, "by-move pattern here") - .span_label(by_ref_span, "both by-ref and by-move used") - .emit(); + } else if let Some(_by_ref_span) = by_ref_span { + span_vec.push(p.span); } }; @@ -567,7 +559,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, ty::BindByValue(..) => { let pat_ty = cx.tables.node_id_to_type(p.hir_id); if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) { - check_move(p, sub.as_ref().map(|p| &**p)); + check_move(p, sub.as_ref().map(|p| &**p), span_vec); } } _ => {} @@ -579,6 +571,20 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, true }); } + if !span_vec.is_empty(){ + let span = MultiSpan::from_spans(span_vec.clone()); + let mut err = struct_span_err!( + cx.tcx.sess, + span, + E0009, + "cannot bind by-move and by-ref in the same pattern", + ); + err.span_label(by_ref_span.unwrap(), "both by-ref and by-move used"); + for span in span_vec.iter(){ + err.span_label(*span, "by-move pattern here"); + } + err.emit(); + } } /// Ensures that a pattern guard doesn't borrow by mutable reference or diff --git a/src/test/ui/issue-53840.rs b/src/test/ui/issue-53840.rs new file mode 100644 index 00000000000..ece3caf78e2 --- /dev/null +++ b/src/test/ui/issue-53840.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +enum E { + Foo(String, String, String), +} + +struct Bar { + a: String, + b: String, +} + +fn main() { + let bar = Bar { a: "1".to_string(), b: "2".to_string() }; + match E::Foo("".into(), "".into(), "".into()) { + E::Foo(a, b, ref c) => {} + } + match bar { + Bar {a, ref b} => {} + } +} diff --git a/src/test/ui/issue-53840.stderr b/src/test/ui/issue-53840.stderr new file mode 100644 index 00000000000..961e4c0ff62 --- /dev/null +++ b/src/test/ui/issue-53840.stderr @@ -0,0 +1,20 @@ +error[E0009]: cannot bind by-move and by-ref in the same pattern + --> $DIR/issue-53840.rs:22:16 + | +LL | E::Foo(a, b, ref c) => {} + | ^ ^ ----- both by-ref and by-move used + | | | + | | by-move pattern here + | by-move pattern here + +error[E0009]: cannot bind by-move and by-ref in the same pattern + --> $DIR/issue-53840.rs:25:14 + | +LL | Bar {a, ref b} => {} + | ^ ----- both by-ref and by-move used + | | + | by-move pattern here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0009`. |
