diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 0e85d7cc0752d8e33b8eb4c6991581ef84d21c7e..b39c415216837b0883be64cba48c49b47959def8 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -38,7 +38,6 @@ E0017, E0019, E0020, - E0021, E0022, E0023, E0024, @@ -62,7 +61,6 @@ E0045, E0046, E0047, - E0048, E0049, E0050, E0051, @@ -117,8 +115,6 @@ E0109, E0110, E0113, - E0114, - E0115, E0116, E0117, E0118, @@ -152,5 +148,7 @@ E0158, E0159, E0161, - E0162 + E0162, + E0163, + E0164 ) diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index b5af2b26b295bc842965150b989604e0465cbe2f..18e2e6c4f09b536147d006bba5f8cea73d5b2587 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -382,26 +382,43 @@ pub fn check_struct_like_enum_variant_pat(pcx: &pat_ctxt, // Find the variant that was specified. match tcx.def_map.borrow().find(&pat_id) { - Some(&def::DefVariant(found_enum_id, variant_id, _)) + Some(&def::DefVariant(found_enum_id, variant_id, true)) if found_enum_id == enum_id => { // Get the struct fields from this struct-like enum variant. - let class_fields = ty::lookup_struct_fields(tcx, variant_id); - - check_struct_pat_fields(pcx, span, fields, class_fields, + let struct_fields = ty::lookup_struct_fields(tcx, variant_id); + check_struct_pat_fields(pcx, span, fields, struct_fields, variant_id, substitutions, etc); + fcx.write_ty(pat_id, expected); + } + Some(&def::DefVariant(_, _, false)) => { + let name = pprust::path_to_string(path); + span_err!(tcx.sess, span, E0163, + "`{}` does not name a struct variant", name); + fcx.write_error(pat_id); + } + Some(&def::DefVariant(_, _, true)) => { + let name = pprust::path_to_string(path); + span_err!(tcx.sess, span, E0164, + "`{}` does not name a variant of the type being matched against", name); + fcx.write_error(pat_id); } Some(&def::DefStruct(..)) | - Some(&def::DefVariant(..)) | Some(&def::DefTy(..)) => { let name = pprust::path_to_string(path); span_err!(tcx.sess, span, E0028, - "mismatched types: expected `{}`, found `{}`", - fcx.infcx().ty_to_string(expected), name); + "`{}` does not name a variant", name); + fcx.write_error(pat_id); } _ => { tcx.sess.span_bug(span, "resolve didn't write in variant"); } } + + if ty::type_is_error(fcx.node_ty(pat_id)) { + for field in fields.iter() { + check_pat(pcx, &*field.pat, ty::mk_err()); + } + } } // Pattern checking is top-down rather than bottom-up so that bindings get diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index bb490273e9f0d66e59b425f5a73e591d29f8ab44..75a412325be4182c7a5517b2af7b6f3727441adf 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -4330,7 +4330,7 @@ fn check_struct_fields_on_error(fcx: &FnCtxt, // Resolve the path. let def = tcx.def_map.borrow().find(&id).map(|i| *i); let struct_id = match def { - Some(def::DefVariant(enum_id, variant_id, _)) => { + Some(def::DefVariant(enum_id, variant_id, true)) => { check_struct_enum_variant(fcx, id, expr.span, enum_id, variant_id, fields.as_slice()); enum_id diff --git a/src/test/compile-fail/issue-15896.rs b/src/test/compile-fail/issue-15896.rs index a873c1e3b3f1d826322b38bc79fb5291a4bc496c..b7fa54e5c1883ff4dd55ec7a9e650cb385022a3d 100644 --- a/src/test/compile-fail/issue-15896.rs +++ b/src/test/compile-fail/issue-15896.rs @@ -18,7 +18,7 @@ enum E { B(R, Tau) } let e = B(REB(()), Tau { t: 3 }); let u = match e { B( - Tau{t: x}, //~ ERROR mismatched types + Tau{t: x}, //~ ERROR `Tau` does not name a variant _) => x, }; } diff --git a/src/test/compile-fail/issue-17405.rs b/src/test/compile-fail/issue-17405.rs new file mode 100644 index 0000000000000000000000000000000000000000..b80cfb521ef1d92f6dbcb193843622835e3fb5e3 --- /dev/null +++ b/src/test/compile-fail/issue-17405.rs @@ -0,0 +1,19 @@ +// Copyright 2014 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 Foo { + Bar(int) +} + +fn main() { + match Bar(1i) { + Foo { i } => () //~ ERROR `Foo` does not name a variant + } +} diff --git a/src/test/compile-fail/issue-17518.rs b/src/test/compile-fail/issue-17518.rs new file mode 100644 index 0000000000000000000000000000000000000000..0410fadeb7892b3fddab9b8f031c365376c71914 --- /dev/null +++ b/src/test/compile-fail/issue-17518.rs @@ -0,0 +1,17 @@ +// Copyright 2014 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 SomeEnum { + E +} + +fn main() { + E { name: "foobar" }; //~ ERROR `E` does not name a structure +} diff --git a/src/test/compile-fail/issue-17800.rs b/src/test/compile-fail/issue-17800.rs new file mode 100644 index 0000000000000000000000000000000000000000..8ef016e3fd5a7db014d896999dd79013b53195c3 --- /dev/null +++ b/src/test/compile-fail/issue-17800.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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 MyOption { + MySome(T), + MyNone, +} + +fn main() { + match MySome(42i) { + MySome { x: 42i } => (), //~ ERROR `MySome` does not name a struct variant + _ => (), + } +}