From 3d7099a9682e1911b18cf440738ab97ae2fecc6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Aug 2018 16:46:28 -0700 Subject: [PATCH] Do not emit E0277 on incorrect tuple destructured binding --- src/librustc_typeck/check/_match.rs | 15 ++++++++-- src/librustc_typeck/check/demand.rs | 1 + .../ui/elide-errors-on-mismatched-tuple.rs | 28 +++++++++++++++++++ .../elide-errors-on-mismatched-tuple.stderr | 12 ++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/elide-errors-on-mismatched-tuple.rs create mode 100644 src/test/ui/elide-errors-on-mismatched-tuple.stderr diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 2a8ee4bd8df0e..ca2b892018b5f 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -299,10 +299,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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 self.has_errors.get() { + let element_tys_iter = (0..max_len).map(|_| tcx.types.err); + let element_tys = tcx.mk_type_list(element_tys_iter); + for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { + self.check_pat_walk(elem, &tcx.types.err, def_bm, true); + } + tcx.mk_ty(ty::TyTuple(element_tys)) + } 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/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 4e22ead8db987..47bbc95aa496b 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -50,6 +50,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { if let Some(mut err) = self.demand_eqtype_diag(sp, expected, actual) { + self.has_errors.set(true); err.emit(); } } 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`.