diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 2a8ee4bd8df0e..7f65a5f0b5a63 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -298,11 +298,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { TypeVariableOrigin::TypeInference(pat.span))); let element_tys = tcx.mk_type_list(element_tys_iter); let pat_ty = tcx.mk_ty(ty::Tuple(element_tys)); - self.demand_eqtype(pat.span, expected, pat_ty); - for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat_walk(elem, &element_tys[i], def_bm, true); + if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) { + err.emit(); + // Walk subpatterns with an expected type of `err` in this case to silence + // further errors being emitted when using the bindings. #50333 + let element_tys_iter = (0..max_len).map(|_| tcx.types.err); + for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { + self.check_pat_walk(elem, &tcx.types.err, def_bm, true); + } + tcx.mk_tup(element_tys_iter) + } else { + for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { + self.check_pat_walk(elem, &element_tys[i], def_bm, true); + } + pat_ty } - pat_ty } PatKind::Box(ref inner) => { let inner_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(inner.span)); diff --git a/src/test/ui/elide-errors-on-mismatched-tuple.rs b/src/test/ui/elide-errors-on-mismatched-tuple.rs new file mode 100644 index 0000000000000..68e579788bca1 --- /dev/null +++ b/src/test/ui/elide-errors-on-mismatched-tuple.rs @@ -0,0 +1,28 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Hide irrelevant E0277 errors (#50333) + +trait T {} + +struct A; +impl T for A {} +impl A { + fn new() -> Self { + Self {} + } +} + +fn main() { + let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three + //~^ ERROR mismatched types + let ts: Vec<&T> = vec![&a, &b, &c]; + // There is no E0277 error above, as `a`, `b` and `c` are `TyErr` +} diff --git a/src/test/ui/elide-errors-on-mismatched-tuple.stderr b/src/test/ui/elide-errors-on-mismatched-tuple.stderr new file mode 100644 index 0000000000000..b901175d53450 --- /dev/null +++ b/src/test/ui/elide-errors-on-mismatched-tuple.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/elide-errors-on-mismatched-tuple.rs:24:9 + | +LL | let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three + | ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements + | + = note: expected type `(A, A)` + found type `(_, _, _)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`.