]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #35138 - petrochenkov:clarify, r=eddyb
authorbors <bors@rust-lang.org>
Sat, 13 Aug 2016 02:38:46 +0000 (19:38 -0700)
committerGitHub <noreply@github.com>
Sat, 13 Aug 2016 02:38:46 +0000 (19:38 -0700)
Implement RFC 1506 "Clarify the relationships between various kinds of structs and variants"

cc https://github.com/rust-lang/rust/issues/35626

27 files changed:
src/librustc_passes/ast_validation.rs
src/librustc_typeck/check/mod.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/parser.rs
src/test/compile-fail/E0071.rs
src/test/compile-fail/auxiliary/empty-struct.rs
src/test/compile-fail/empty-struct-braces-pat-2.rs
src/test/compile-fail/empty-struct-braces-pat-3.rs
src/test/compile-fail/empty-struct-tuple-pat.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-unit-pat-1.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-unit-pat-2.rs [new file with mode: 0644]
src/test/compile-fail/empty-struct-unit-pat.rs [deleted file]
src/test/compile-fail/feature-gate-relaxed-adts-2.rs [new file with mode: 0644]
src/test/compile-fail/feature-gate-relaxed-adts.rs [new file with mode: 0644]
src/test/compile-fail/issue-12560-1.rs [deleted file]
src/test/compile-fail/issue-12560-2.rs [deleted file]
src/test/compile-fail/issue-16819.rs
src/test/compile-fail/issue-17800.rs
src/test/compile-fail/issue-27831.rs [deleted file]
src/test/compile-fail/issue-4736.rs
src/test/compile-fail/numeric-fields.rs [new file with mode: 0644]
src/test/compile-fail/struct-no-fields-enumlike.rs [deleted file]
src/test/run-pass/auxiliary/empty-struct.rs
src/test/run-pass/empty-struct-braces-gate-1.rs [deleted file]
src/test/run-pass/empty-struct-braces-gate-2.rs [deleted file]
src/test/run-pass/empty-struct-braces.rs
src/test/run-pass/numeric-fields.rs [new file with mode: 0644]

index 341c9d820e6519b060445ec621a56a3cc49faee4..1e8da29ee74002bbd5f37b5ead3935d08c62382c 100644 (file)
@@ -197,27 +197,6 @@ fn visit_foreign_item(&mut self, fi: &ForeignItem) {
         visit::walk_foreign_item(self, fi)
     }
 
-    fn visit_variant_data(&mut self,
-                          vdata: &VariantData,
-                          _: Ident,
-                          _: &Generics,
-                          _: NodeId,
-                          span: Span) {
-        if vdata.fields().is_empty() {
-            if vdata.is_tuple() {
-                self.err_handler()
-                    .struct_span_err(span,
-                                     "empty tuple structs and enum variants are not allowed, use \
-                                      unit structs and enum variants instead")
-                    .span_help(span,
-                               "remove trailing `()` to make a unit struct or unit enum variant")
-                    .emit();
-            }
-        }
-
-        visit::walk_struct_def(self, vdata)
-    }
-
     fn visit_vis(&mut self, vis: &Visibility) {
         match *vis {
             Visibility::Restricted { ref path, .. } => {
index c2c93161ce703473e02f90bb0928809b7cb03aed..0c8e6d990a64443f08cb6e5c24c64cda5d6dd153 100644 (file)
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::{self, Spanned};
+use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::parse::token::{self, InternedString, keywords};
 use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
@@ -1700,7 +1701,12 @@ pub fn instantiate_type_path(&self,
                                  node_id: ast::NodeId)
                                  -> Ty<'tcx> {
         debug!("instantiate_type_path(did={:?}, path={:?})", did, path);
-        let type_scheme = self.tcx.lookup_item_type(did);
+        let mut type_scheme = self.tcx.lookup_item_type(did);
+        if type_scheme.ty.is_fn() {
+            // Tuple variants have fn type even in type namespace, extract true variant type from it
+            let fn_ret = self.tcx.no_late_bound_regions(&type_scheme.ty.fn_ret()).unwrap().unwrap();
+            type_scheme = ty::TypeScheme { ty: fn_ret, generics: type_scheme.generics }
+        }
         let type_predicates = self.tcx.lookup_predicates(did);
         let substs = AstConv::ast_path_substs_for_ty(self, self,
                                                      path.span,
@@ -3244,19 +3250,24 @@ pub fn check_struct_path(&self,
             }
             _ => None
         };
-        if variant.is_none() || variant.unwrap().kind == ty::VariantKind::Tuple {
-            // Reject tuple structs for now, braced and unit structs are allowed.
+
+        if let Some(variant) = variant {
+            if variant.kind == ty::VariantKind::Tuple &&
+                    !self.tcx.sess.features.borrow().relaxed_adts {
+                emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
+                                 "relaxed_adts", span, GateIssue::Language,
+                                 "tuple structs and variants in struct patterns are unstable");
+            }
+            let ty = self.instantiate_type_path(def.def_id(), path, node_id);
+            Some((variant, ty))
+        } else {
             struct_span_err!(self.tcx.sess, path.span, E0071,
                              "`{}` does not name a struct or a struct variant",
                              pprust::path_to_string(path))
                 .span_label(path.span, &format!("not a struct"))
                 .emit();
-
-            return None;
+            None
         }
-
-        let ty = self.instantiate_type_path(def.def_id(), path, node_id);
-        Some((variant.unwrap(), ty))
     }
 
     fn check_expr_struct(&self,
index f550e7d2a0515e1f2da1f7599a1746d9a0bebd93..ad52184a6dcb0cd658cb607b31fc5a97352ad3b6 100644 (file)
@@ -280,7 +280,11 @@ pub fn new() -> Features {
     (active, dotdot_in_tuple_patterns, "1.10.0", Some(33627)),
 
     // Allows `impl Trait` in function return types.
-    (active, conservative_impl_trait, "1.12.0", Some(34511))
+    (active, conservative_impl_trait, "1.12.0", Some(34511)),
+
+    // Allows tuple structs and variants in more contexts,
+    // Permits numeric fields in struct expressions and patterns.
+    (active, relaxed_adts, "1.12.0", Some(35626))
 );
 
 declare_features! (
@@ -1022,9 +1026,8 @@ fn visit_pat(&mut self, pattern: &ast::Pat) {
             }
             PatKind::TupleStruct(_, ref fields, ddpos)
                     if ddpos.is_none() && fields.is_empty() => {
-                self.context.span_handler.struct_span_err(pattern.span,
-                                                          "nullary enum variants are written with \
-                                                           no trailing `( )`").emit();
+                gate_feature_post!(&self, relaxed_adts, pattern.span,
+                                   "empty tuple structs patterns are unstable");
             }
             _ => {}
         }
@@ -1107,6 +1110,19 @@ fn visit_impl_item(&mut self, ii: &ast::ImplItem) {
         visit::walk_impl_item(self, ii);
     }
 
+    fn visit_variant_data(&mut self, vdata: &ast::VariantData, _: ast::Ident,
+                          _: &ast::Generics, _: NodeId, span: Span) {
+        if vdata.fields().is_empty() {
+            if vdata.is_tuple() {
+                gate_feature_post!(&self, relaxed_adts, span,
+                                   "empty tuple structs and enum variants are unstable, \
+                                    use unit structs and enum variants instead");
+            }
+        }
+
+        visit::walk_struct_def(self, vdata)
+    }
+
     fn visit_vis(&mut self, vis: &ast::Visibility) {
         let span = match *vis {
             ast::Visibility::Crate(span) => span,
index 1b32632a06f4e2b2997df194f7029387231fffa0..4c279b2fe48327dfda1f94e746d1ec445bba6e28 100644 (file)
@@ -2009,10 +2009,19 @@ pub fn parse_mutability(&mut self) -> PResult<'a, Mutability> {
         }
     }
 
+    pub fn parse_field_name(&mut self) -> PResult<'a, Ident> {
+        if let token::Literal(token::Integer(name), None) = self.token {
+            self.bump();
+            Ok(Ident::with_empty_ctxt(name))
+        } else {
+            self.parse_ident()
+        }
+    }
+
     /// Parse ident COLON expr
     pub fn parse_field(&mut self) -> PResult<'a, Field> {
         let lo = self.span.lo;
-        let i = self.parse_ident()?;
+        let i = self.parse_field_name()?;
         let hi = self.last_span.hi;
         self.expect(&token::Colon)?;
         let e = self.parse_expr()?;
@@ -3508,7 +3517,7 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPa
             // Check if a colon exists one ahead. This means we're parsing a fieldname.
             let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
                 // Parsing a pattern of the form "fieldname: pat"
-                let fieldname = self.parse_ident()?;
+                let fieldname = self.parse_field_name()?;
                 self.bump();
                 let pat = self.parse_pat()?;
                 hi = pat.span.hi;
index 6f0e55efffc921dc31a991972b007f515b5f46de..c13ba7bf136712efd1cb50732de9e8a36b81688e 100644 (file)
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum Foo { FirstValue(i32) }
+enum Foo {}
 
 fn main() {
-    let u = Foo::FirstValue { value: 0 };
-    //~^ ERROR `Foo::FirstValue` does not name a struct or a struct variant [E0071]
+    let u = Foo { value: 0 };
+    //~^ ERROR `Foo` does not name a struct or a struct variant [E0071]
     //~| NOTE not a struct
 
     let t = u32 { value: 4 };
index 22f65c2b0d8f86470130de485c70d5f33d514e99..dcbb0ce178bd8c487df447ee0124c0e535de5a6a 100644 (file)
@@ -8,10 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(relaxed_adts)]
+
 pub struct XEmpty1 {}
 pub struct XEmpty2;
+pub struct XEmpty6();
 
 pub enum XE {
     XEmpty3 {},
     XEmpty4,
+    XEmpty5(),
 }
index 0522a654a8528200a661fda6393ce0e836675e9e..52481517ce7512ca5289ac5eda9ed3cafd49da7d 100644 (file)
@@ -12,6 +12,8 @@
 
 // aux-build:empty-struct.rs
 
+#![feature(relaxed_adts)]
+
 extern crate empty_struct;
 use empty_struct::*;
 
@@ -21,13 +23,12 @@ fn main() {
     let e1 = Empty1 {};
     let xe1 = XEmpty1 {};
 
-    // Rejected by parser as yet
-    // match e1 {
-    //     Empty1() => () // ERROR unresolved enum variant, struct or const `Empty1`
-    // }
-    // match xe1 {
-    //     XEmpty1() => () // ERROR unresolved enum variant, struct or const `XEmpty1`
-    // }
+    match e1 {
+        Empty1() => () //~ ERROR unresolved variant or struct `Empty1`
+    }
+    match xe1 {
+        XEmpty1() => () //~ ERROR unresolved variant or struct `XEmpty1`
+    }
     match e1 {
         Empty1(..) => () //~ ERROR unresolved variant or struct `Empty1`
     }
index 88249fc422f2cb8c37e0a22e4bb2ad5eb89a9ac8..cb859fe7501c677f7cf1232a7fb31a721f19e47e 100644 (file)
@@ -12,6 +12,8 @@
 
 // aux-build:empty-struct.rs
 
+#![feature(relaxed_adts)]
+
 extern crate empty_struct;
 use empty_struct::*;
 
@@ -23,13 +25,12 @@ fn main() {
     let e3 = E::Empty3 {};
     let xe3 = XE::XEmpty3 {};
 
-    // Rejected by parser as yet
-    // match e3 {
-    //     E::Empty3() => () // ERROR `E::Empty3` does not name a tuple variant or a tuple struct
-    // }
-    // match xe3 {
-    //     E::Empty3() => () // ERROR `XE::XEmpty3` does not name a tuple variant or a tuple struct
-    // }
+    match e3 {
+        E::Empty3() => () //~ ERROR `E::Empty3` does not name a tuple variant or a tuple struct
+    }
+    match xe3 {
+        XE::XEmpty3() => () //~ ERROR `XE::XEmpty3` does not name a tuple variant or a tuple struct
+    }
     match e3 {
         E::Empty3(..) => () //~ ERROR `E::Empty3` does not name a tuple variant or a tuple struct
     }
diff --git a/src/test/compile-fail/empty-struct-tuple-pat.rs b/src/test/compile-fail/empty-struct-tuple-pat.rs
new file mode 100644 (file)
index 0000000..be90e3b
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Can't use unit struct as enum pattern
+
+// aux-build:empty-struct.rs
+
+#![feature(relaxed_adts)]
+
+extern crate empty_struct;
+use empty_struct::*;
+
+struct Empty2();
+
+enum E {
+    Empty4()
+}
+
+// remove attribute after warning cycle and promoting warnings to errors
+fn main() {
+    let e2 = Empty2();
+    let e4 = E::Empty4();
+    let xe6 = XEmpty6();
+    let xe5 = XE::XEmpty5();
+
+    match e2 {
+        Empty2 => () //~ ERROR `Empty2` does not name a unit variant, unit struct or a constant
+    }
+    match xe6 {
+        XEmpty6 => () //~ ERROR `XEmpty6` does not name a unit variant, unit struct or a constant
+    }
+
+    match e4 {
+        E::Empty4 => () //~ ERROR `E::Empty4` does not name a unit variant, unit struct or a
+    }
+    match xe5 {
+        XE::XEmpty5 => (), //~ ERROR `XE::XEmpty5` does not name a unit variant, unit struct or a
+        _ => {},
+    }
+}
diff --git a/src/test/compile-fail/empty-struct-unit-pat-1.rs b/src/test/compile-fail/empty-struct-unit-pat-1.rs
new file mode 100644 (file)
index 0000000..aec4ad4
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Can't use unit struct as enum pattern
+
+// aux-build:empty-struct.rs
+
+#![feature(relaxed_adts)]
+
+extern crate empty_struct;
+use empty_struct::*;
+
+struct Empty2;
+
+enum E {
+    Empty4
+}
+
+// remove attribute after warning cycle and promoting warnings to errors
+fn main() {
+    let e2 = Empty2;
+    let e4 = E::Empty4;
+    let xe2 = XEmpty2;
+    let xe4 = XE::XEmpty4;
+
+    match e2 {
+        Empty2(..) => () //~ ERROR `Empty2` does not name a tuple variant or a tuple struct
+            //~^ WARNING hard error
+    }
+    match xe2 {
+        XEmpty2(..) => () //~ ERROR `XEmpty2` does not name a tuple variant or a tuple struct
+            //~^ WARNING hard error
+    }
+
+    match e4 {
+        E::Empty4(..) => () //~ ERROR `E::Empty4` does not name a tuple variant or a tuple struct
+            //~^ WARNING hard error
+    }
+    match xe4 {
+        XE::XEmpty4(..) => (), //~ ERROR `XE::XEmpty4` does not name a tuple variant or a tuple
+            //~^ WARNING hard error
+        _ => {},
+    }
+}
diff --git a/src/test/compile-fail/empty-struct-unit-pat-2.rs b/src/test/compile-fail/empty-struct-unit-pat-2.rs
new file mode 100644 (file)
index 0000000..6375a7f
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Can't use unit struct as enum pattern
+
+// aux-build:empty-struct.rs
+
+#![feature(relaxed_adts)]
+
+extern crate empty_struct;
+use empty_struct::*;
+
+struct Empty2;
+
+enum E {
+    Empty4
+}
+
+// remove attribute after warning cycle and promoting warnings to errors
+fn main() {
+    let e2 = Empty2;
+    let e4 = E::Empty4;
+    let xe2 = XEmpty2;
+    let xe4 = XE::XEmpty4;
+
+    match e2 {
+        Empty2() => () //~ ERROR `Empty2` does not name a tuple variant or a tuple struct
+    }
+    match xe2 {
+        XEmpty2() => () //~ ERROR `XEmpty2` does not name a tuple variant or a tuple struct
+    }
+
+    match e4 {
+        E::Empty4() => () //~ ERROR `E::Empty4` does not name a tuple variant or a tuple struct
+    }
+    match xe4 {
+        XE::XEmpty4() => (), //~ ERROR `XE::XEmpty4` does not name a tuple variant or a tuple
+        _ => {},
+    }
+}
diff --git a/src/test/compile-fail/empty-struct-unit-pat.rs b/src/test/compile-fail/empty-struct-unit-pat.rs
deleted file mode 100644 (file)
index 0573376..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2015 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Can't use unit struct as enum pattern
-
-// aux-build:empty-struct.rs
-
-extern crate empty_struct;
-use empty_struct::*;
-
-struct Empty2;
-
-enum E {
-    Empty4
-}
-
-// remove attribute after warning cycle and promoting warnings to errors
-fn main() {
-    let e2 = Empty2;
-    let e4 = E::Empty4;
-    let xe2 = XEmpty2;
-    let xe4 = XE::XEmpty4;
-
-    // Rejected by parser as yet
-    // match e2 {
-    //     Empty2() => () // ERROR `Empty2` does not name a tuple variant or a tuple struct
-    // }
-    // match xe2 {
-    //     XEmpty2() => () // ERROR `XEmpty2` does not name a tuple variant or a tuple struct
-    // }
-    match e2 {
-        Empty2(..) => () //~ ERROR `Empty2` does not name a tuple variant or a tuple struct
-            //~^ WARNING hard error
-    }
-    match xe2 {
-        XEmpty2(..) => () //~ ERROR `XEmpty2` does not name a tuple variant or a tuple struct
-            //~^ WARNING hard error
-    }
-    // Rejected by parser as yet
-    // match e4 {
-    //     E::Empty4() => () // ERROR `E::Empty4` does not name a tuple variant or a tuple struct
-    // }
-    // match xe4 {
-    //     XE::XEmpty4() => (), // ERROR `XE::XEmpty4` does not name a tuple variant or a tuple
-    //     _ => {},
-    // }
-    match e4 {
-        E::Empty4(..) => () //~ ERROR `E::Empty4` does not name a tuple variant or a tuple struct
-            //~^ WARNING hard error
-    }
-    match xe4 {
-        XE::XEmpty4(..) => (), //~ ERROR `XE::XEmpty4` does not name a tuple variant or a tuple
-            //~^ WARNING hard error
-        _ => {},
-    }
-}
diff --git a/src/test/compile-fail/feature-gate-relaxed-adts-2.rs b/src/test/compile-fail/feature-gate-relaxed-adts-2.rs
new file mode 100644 (file)
index 0000000..a75f264
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2016 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Z(u8, u8);
+
+enum E {
+    U(u8, u8),
+}
+
+fn main() {
+    match Z(0, 1) {
+        Z{..} => {} //~ ERROR tuple structs and variants in struct patterns are unstable
+    }
+    match E::U(0, 1) {
+        E::U{..} => {} //~ ERROR tuple structs and variants in struct patterns are unstable
+    }
+
+    let z1 = Z(0, 1);
+    let z2 = Z { ..z1 }; //~ ERROR tuple structs and variants in struct patterns are unstable
+}
diff --git a/src/test/compile-fail/feature-gate-relaxed-adts.rs b/src/test/compile-fail/feature-gate-relaxed-adts.rs
new file mode 100644 (file)
index 0000000..dc5e347
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2016 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct S(); //~ ERROR empty tuple structs and enum variants are unstable
+struct Z(u8, u8);
+
+enum E {
+    V(), //~ ERROR empty tuple structs and enum variants are unstable
+    U(u8, u8),
+}
+
+fn main() {
+    match S() {
+        S() => {} //~ ERROR empty tuple structs patterns are unstable
+    }
+    match E::V() {
+        E::V() => {} //~ ERROR empty tuple structs patterns are unstable
+    }
+}
diff --git a/src/test/compile-fail/issue-12560-1.rs b/src/test/compile-fail/issue-12560-1.rs
deleted file mode 100644 (file)
index 80f551e..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// For style and consistency reasons, non-parametrized enum variants must
-// be used simply as `ident` instead of `ident ()`.
-// This test-case covers enum declaration.
-
-enum Foo {
-    Bar(), //~ ERROR empty tuple structs and enum variants are not allowed
-    //~^ HELP remove trailing `()` to make a unit struct or unit enum variant
-    Baz(), //~ ERROR empty tuple structs and enum variants are not allowed
-    //~^ HELP remove trailing `()` to make a unit struct or unit enum variant
-    Bazar
-}
-
-fn main() {
-    println!("{}", match Bar { Bar => 1, Baz => 2, Bazar => 3 }) //~ ERROR unresolved name `Bar`
-}
diff --git a/src/test/compile-fail/issue-12560-2.rs b/src/test/compile-fail/issue-12560-2.rs
deleted file mode 100644 (file)
index 9cbe2eb..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -Z continue-parse-after-error
-
-// For style and consistency reasons, non-parametrized enum variants must
-// be used simply as `ident` instead of `ident ()`.
-// This test-case covers enum matching.
-
-enum Foo {
-    Bar,
-    Baz,
-    Bazar
-}
-
-fn main() {
-    println!("{}", match Bar {
-        Bar() => 1, //~ ERROR nullary enum variants are written with no trailing `( )`
-        Baz() => 2, //~ ERROR nullary enum variants are written with no trailing `( )`
-        Bazar => 3
-    })
-}
index b229b91c7cd14d353b2df8a42bff9b8c09793677..4301b47f2e9b29ce956f8450d3d69c4fc543bccf 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct TS ( //~ ERROR empty tuple structs and enum variants are not allowed
+struct TS ( //~ ERROR empty tuple structs and enum variants are unstable
     #[cfg(untrue)]
     i32,
 );
 
 enum E {
-    TV ( //~ ERROR empty tuple structs and enum variants are not allowed
+    TV ( //~ ERROR empty tuple structs and enum variants are unstable
         #[cfg(untrue)]
         i32,
     )
index 5196b6ea877f887d553e86b306ddba680ed70d3f..58d580a5c1a1ceb6ecf9b8d257e7f55b4a714f46 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(relaxed_adts)]
+
 enum MyOption<T> {
     MySome(T),
     MyNone,
@@ -16,7 +18,8 @@ enum MyOption<T> {
 fn main() {
     match MyOption::MySome(42) {
         MyOption::MySome { x: 42 } => (),
-        //~^ ERROR `MyOption::MySome` does not name a struct or a struct variant
+        //~^ ERROR struct `MyOption::MySome` does not have a field named `x`
+        //~| ERROR pattern does not mention field `0`
         _ => (),
     }
 }
diff --git a/src/test/compile-fail/issue-27831.rs b/src/test/compile-fail/issue-27831.rs
deleted file mode 100644 (file)
index e20e6ea..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2015 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Foo(u32);
-struct Bar;
-
-enum Enum {
-    Foo(u32),
-    Bar
-}
-
-fn main() {
-    let x = Foo(1);
-    Foo { ..x }; //~ ERROR `Foo` does not name a struct or a struct variant
-    let Foo { .. } = x; //~ ERROR `Foo` does not name a struct
-
-    let x = Bar;
-    Bar { ..x };
-    let Bar { .. } = x;
-
-    match Enum::Bar {
-        Enum::Bar { .. }
-           => {}
-        Enum::Foo { .. } //~ ERROR `Enum::Foo` does not name a struct
-           => {}
-    }
-}
index 55983c672aa08a8553ce28932d2db5202f277b63..a8a1b1482fc08b4ad0e69473d22679e32e9bdc08 100644 (file)
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(relaxed_adts)]
+
 struct NonCopyable(());
 
 fn main() {
-    let z = NonCopyable{ p: () }; //~ ERROR `NonCopyable` does not name a struct or a struct variant
+    let z = NonCopyable{ p: () }; //~ ERROR structure `NonCopyable` has no field named `p`
 }
diff --git a/src/test/compile-fail/numeric-fields.rs b/src/test/compile-fail/numeric-fields.rs
new file mode 100644 (file)
index 0000000..480d2dc
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(relaxed_adts)]
+
+struct S(u8, u16);
+
+fn main() {
+    let s = S{0b1: 10, 0: 11}; //~ ERROR structure `S` has no field named `0b1`
+    match s {
+        S{0: a, 0x1: b, ..} => {} //~ ERROR does not have a field named `0x1`
+    }
+}
diff --git a/src/test/compile-fail/struct-no-fields-enumlike.rs b/src/test/compile-fail/struct-no-fields-enumlike.rs
deleted file mode 100644 (file)
index 6bdbae1..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct Foo(); //~ ERROR empty tuple structs and enum variants are not allowed
-
-fn main() {}
index 22f65c2b0d8f86470130de485c70d5f33d514e99..b599d7bee73defca8eb7261063c7ebcde99bf465 100644 (file)
@@ -8,10 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(relaxed_adts)]
+
 pub struct XEmpty1 {}
 pub struct XEmpty2;
+pub struct XEmpty7();
 
 pub enum XE {
     XEmpty3 {},
     XEmpty4,
+    XEmpty6(),
 }
diff --git a/src/test/run-pass/empty-struct-braces-gate-1.rs b/src/test/run-pass/empty-struct-braces-gate-1.rs
deleted file mode 100644 (file)
index 8287e15..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2015 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Feature gate test for empty struct with braces
-// Can't define an empty braced struct
-
-struct Empty1 {}
-struct Empty2;
-
-enum E {
-    Empty4 {},
-    Empty5,
-}
-
-fn main() {
-}
diff --git a/src/test/run-pass/empty-struct-braces-gate-2.rs b/src/test/run-pass/empty-struct-braces-gate-2.rs
deleted file mode 100644 (file)
index 0ec3c89..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2015 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Feature gate test for empty struct with braces
-// Can't use braced expressions and patterns with structs defined without braces
-
-struct Empty2;
-
-enum E {
-    Empty5,
-}
-
-fn main() {
-    let e2: Empty2 = Empty2 {};
-    let e2: Empty2 = Empty2;
-    let e5: E = E::Empty5 {};
-    let e5: E = E::Empty5;
-
-    match e2 {
-        Empty2 {} => {}
-    }
-    match e2 {
-        Empty2 => {}
-    }
-    match e2 {
-        Empty2 { .. } => {}
-    }
-    match e5 {
-        E::Empty5 {} => {}
-    }
-    match e5 {
-        E::Empty5 => {}
-    }
-    match e5 {
-        E::Empty5 { .. } => {}
-    }
-
-    let e22 = Empty2 { ..e2 };
-}
index 0060150fbece01b90c07e411bfb31b4db4ae8a58..48966f24a2e5eca4afead2914955c92cf5ed0a94 100644 (file)
 
 // aux-build:empty-struct.rs
 
+#![feature(relaxed_adts)]
+
 extern crate empty_struct;
 use empty_struct::*;
 
 struct Empty1 {}
 struct Empty2;
+struct Empty7();
 
 #[derive(PartialEq, Eq)]
 struct Empty3 {}
@@ -27,6 +30,7 @@ struct Empty3 {}
 enum E {
     Empty4 {},
     Empty5,
+    Empty6(),
 }
 
 fn local() {
@@ -38,6 +42,12 @@ fn local() {
     let e4: E = E::Empty4 {};
     let e5: E = E::Empty5 {};
     let e5: E = E::Empty5;
+    let e6: E = E::Empty6 {};
+    let e6: E = E::Empty6();
+    let ctor6: fn() -> E = E::Empty6;
+    let e7: Empty7 = Empty7 {};
+    let e7: Empty7 = Empty7();
+    let ctor7: fn() -> Empty7 = Empty7;
 
     match e1 {
         Empty1 {} => {}
@@ -56,6 +66,13 @@ fn local() {
         E::Empty5 {} => {}
         _ => {}
     }
+    match e6 {
+        E::Empty6 {} => {}
+        _ => {}
+    }
+    match e7 {
+        Empty7 {} => {}
+    }
 
     match e1 {
         Empty1 { .. } => {}
@@ -74,6 +91,13 @@ fn local() {
         E::Empty5 { .. } => {}
         _ => {}
     }
+    match e6 {
+        E::Empty6 { .. } => {}
+        _ => {}
+    }
+    match e7 {
+        Empty7 { .. } => {}
+    }
 
     match e2 {
         Empty2 => {}
@@ -85,10 +109,25 @@ fn local() {
         E::Empty5 => {}
         _ => {}
     }
+    match e6 {
+        E::Empty6() => {}
+        _ => {}
+    }
+    match e6 {
+        E::Empty6(..) => {}
+        _ => {}
+    }
+    match e7 {
+        Empty7() => {}
+    }
+    match e7 {
+        Empty7(..) => {}
+    }
 
     let e11: Empty1 = Empty1 { ..e1 };
     let e22: Empty2 = Empty2 { ..e2 };
     let e33: Empty3 = Empty3 { ..e3 };
+    let e77: Empty7 = Empty7 { ..e7 };
 }
 
 fn xcrate() {
@@ -98,6 +137,12 @@ fn xcrate() {
     let e3: XE = XE::XEmpty3 {};
     let e4: XE = XE::XEmpty4 {};
     let e4: XE = XE::XEmpty4;
+    let e6: XE = XE::XEmpty6 {};
+    let e6: XE = XE::XEmpty6();
+    let ctor6: fn() -> XE = XE::XEmpty6;
+    let e7: XEmpty7 = XEmpty7 {};
+    let e7: XEmpty7 = XEmpty7();
+    let ctor7: fn() -> XEmpty7 = XEmpty7;
 
     match e1 {
         XEmpty1 {} => {}
@@ -113,6 +158,13 @@ fn xcrate() {
         XE::XEmpty4 {} => {}
         _ => {}
     }
+    match e6 {
+        XE::XEmpty6 {} => {}
+        _ => {}
+    }
+    match e7 {
+        XEmpty7 {} => {}
+    }
 
     match e1 {
         XEmpty1 { .. } => {}
@@ -128,6 +180,13 @@ fn xcrate() {
         XE::XEmpty4 { .. } => {}
         _ => {}
     }
+    match e6 {
+        XE::XEmpty6 { .. } => {}
+        _ => {}
+    }
+    match e7 {
+        XEmpty7 { .. } => {}
+    }
 
     match e2 {
         XEmpty2 => {}
@@ -136,9 +195,24 @@ fn xcrate() {
         XE::XEmpty4 => {}
         _ => {}
     }
+    match e6 {
+        XE::XEmpty6() => {}
+        _ => {}
+    }
+    match e6 {
+        XE::XEmpty6(..) => {}
+        _ => {}
+    }
+    match e7 {
+        XEmpty7() => {}
+    }
+    match e7 {
+        XEmpty7(..) => {}
+    }
 
     let e11: XEmpty1 = XEmpty1 { ..e1 };
     let e22: XEmpty2 = XEmpty2 { ..e2 };
+    let e77: XEmpty7 = XEmpty7 { ..e7 };
 }
 
 fn main() {
diff --git a/src/test/run-pass/numeric-fields.rs b/src/test/run-pass/numeric-fields.rs
new file mode 100644 (file)
index 0000000..25e5a2a
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2016 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(relaxed_adts)]
+
+struct S(u8, u16);
+
+fn main() {
+    let s = S{1: 10, 0: 11};
+    match s {
+        S{0: a, 1: b, ..} => {
+            assert_eq!(a, 11);
+            assert_eq!(b, 10);
+        }
+    }
+}