diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 7a31c679d3aa9..a531e17a0cab2 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -723,8 +723,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.demand_eqtype(pat.span, expected, pat_ty); // Type check subpatterns. - self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm); - pat_ty + if self.check_struct_pat_fields(pat_ty, pat.id, pat.span, variant, fields, etc, def_bm) { + pat_ty + } else { + self.tcx.types.err + } } fn check_pat_path(&self, @@ -849,7 +852,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); variant: &'tcx ty::VariantDef, fields: &'gcx [Spanned], etc: bool, - def_bm: ty::BindingMode) { + def_bm: ty::BindingMode) -> bool { let tcx = self.tcx; let (substs, adt) = match adt_ty.sty { @@ -867,6 +870,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); // Keep track of which fields have already appeared in the pattern. let mut used_fields = FxHashMap(); + let mut no_field_errors = true; let mut inexistent_fields = vec![]; // Typecheck each field. @@ -882,6 +886,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); format!("multiple uses of `{}` in pattern", field.name)) .span_label(*occupied.get(), format!("first use of `{}`", field.name)) .emit(); + no_field_errors = false; tcx.types.err } Vacant(vacant) => { @@ -894,6 +899,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); }) .unwrap_or_else(|| { inexistent_fields.push((span, field.name)); + no_field_errors = false; tcx.types.err }) } @@ -992,5 +998,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); diag.emit(); } } + no_field_errors } } diff --git a/src/test/ui/issue-51102.rs b/src/test/ui/issue-51102.rs new file mode 100644 index 0000000000000..c8f106687ae1c --- /dev/null +++ b/src/test/ui/issue-51102.rs @@ -0,0 +1,48 @@ +// 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. + +enum SimpleEnum { + NoState, +} + +struct SimpleStruct { + no_state_here: u64, +} + +fn main() { + let _ = |simple| { + match simple { + SimpleStruct { + state: 0, + //~^ struct `SimpleStruct` does not have a field named `state` [E0026] + .. + } => (), + } + }; + + let _ = |simple| { + match simple { + SimpleStruct { + no_state_here: 0, + no_state_here: 1 + //~^ ERROR field `no_state_here` bound multiple times in the pattern [E0025] + } => (), + } + }; + + let _ = |simple| { + match simple { + SimpleEnum::NoState { + state: 0 + //~^ ERROR variant `SimpleEnum::NoState` does not have a field named `state` [E0026] + } => (), + } + }; +} diff --git a/src/test/ui/issue-51102.stderr b/src/test/ui/issue-51102.stderr new file mode 100644 index 0000000000000..a4bd0fb914fee --- /dev/null +++ b/src/test/ui/issue-51102.stderr @@ -0,0 +1,24 @@ +error[E0026]: struct `SimpleStruct` does not have a field named `state` + --> $DIR/issue-51102.rs:23:17 + | +LL | state: 0, + | ^^^^^^^^ struct `SimpleStruct` does not have this field + +error[E0025]: field `no_state_here` bound multiple times in the pattern + --> $DIR/issue-51102.rs:34:17 + | +LL | no_state_here: 0, + | ---------------- first use of `no_state_here` +LL | no_state_here: 1 + | ^^^^^^^^^^^^^^^^ multiple uses of `no_state_here` in pattern + +error[E0026]: variant `SimpleEnum::NoState` does not have a field named `state` + --> $DIR/issue-51102.rs:43:17 + | +LL | state: 0 + | ^^^^^^^^ variant `SimpleEnum::NoState` does not have this field + +error: aborting due to 3 previous errors + +Some errors occurred: E0025, E0026. +For more information about an error, try `rustc --explain E0025`.