Skip to content

Commit 3d7099a

Browse files
committed
Do not emit E0277 on incorrect tuple destructured binding
1 parent 7ee7207 commit 3d7099a

File tree

4 files changed

+53
-3
lines changed

4 files changed

+53
-3
lines changed

src/librustc_typeck/check/_match.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
299299
let element_tys = tcx.mk_type_list(element_tys_iter);
300300
let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
301301
self.demand_eqtype(pat.span, expected, pat_ty);
302-
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
303-
self.check_pat_walk(elem, &element_tys[i], def_bm, true);
302+
if self.has_errors.get() {
303+
let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
304+
let element_tys = tcx.mk_type_list(element_tys_iter);
305+
for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
306+
self.check_pat_walk(elem, &tcx.types.err, def_bm, true);
307+
}
308+
tcx.mk_ty(ty::TyTuple(element_tys))
309+
} else {
310+
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
311+
self.check_pat_walk(elem, &element_tys[i], def_bm, true);
312+
}
313+
pat_ty
304314
}
305-
pat_ty
306315
}
307316
PatKind::Box(ref inner) => {
308317
let inner_ty = self.next_ty_var(TypeVariableOrigin::TypeInference(inner.span));

src/librustc_typeck/check/demand.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5050

5151
pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
5252
if let Some(mut err) = self.demand_eqtype_diag(sp, expected, actual) {
53+
self.has_errors.set(true);
5354
err.emit();
5455
}
5556
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
11+
// Hide irrelevant E0277 errors (#50333)
12+
13+
trait T {}
14+
15+
struct A;
16+
impl T for A {}
17+
impl A {
18+
fn new() -> Self {
19+
Self {}
20+
}
21+
}
22+
23+
fn main() {
24+
let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three
25+
//~^ ERROR mismatched types
26+
let ts: Vec<&T> = vec![&a, &b, &c];
27+
// There is no E0277 error above, as `a`, `b` and `c` are `TyErr`
28+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/elide-errors-on-mismatched-tuple.rs:24:9
3+
|
4+
LL | let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three
5+
| ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
6+
|
7+
= note: expected type `(A, A)`
8+
found type `(_, _, _)`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)