about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-08-15 21:28:17 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-08-18 01:07:32 +0300
commit28ed8b159237a2704f2308a404b3bd81b676ce17 (patch)
tree50a387623e012f39c2a41a7145a0177c0943c47a
parent7ac11cad3fe85163dd8b0ca1f63af492509f9bfe (diff)
downloadrust-28ed8b159237a2704f2308a404b3bd81b676ce17.tar.gz
rust-28ed8b159237a2704f2308a404b3bd81b676ce17.zip
Fix #[derive] for empty tuple structs/variants
-rw-r--r--src/libsyntax/ext/build.rs2
-rw-r--r--src/libsyntax_ext/deriving/decodable.rs6
-rw-r--r--src/libsyntax_ext/deriving/default.rs4
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs6
-rw-r--r--src/test/run-pass-fulldeps/empty-struct-braces-derive.rs24
5 files changed, 32 insertions, 10 deletions
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 5d6429f7bdf..7600bff9695 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -844,7 +844,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
     fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
         let pat = if subpats.is_empty() {
-            PatKind::Path(None, path)
+            PatKind::Struct(path, Vec::new(), false)
         } else {
             PatKind::TupleStruct(path, subpats, None)
         };
diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs
index 9a332227053..f395f7bd0c4 100644
--- a/src/libsyntax_ext/deriving/decodable.rs
+++ b/src/libsyntax_ext/deriving/decodable.rs
@@ -110,7 +110,7 @@ fn decodable_substructure(cx: &mut ExtCtxt,
     return match *substr.fields {
         StaticStruct(_, ref summary) => {
             let nfields = match *summary {
-                Unnamed(ref fields) => fields.len(),
+                Unnamed(ref fields, _) => fields.len(),
                 Named(ref fields) => fields.len(),
             };
             let read_struct_field = cx.ident_of("read_struct_field");
@@ -193,9 +193,9 @@ fn decode_static_fields<F>(cx: &mut ExtCtxt,
     where F: FnMut(&mut ExtCtxt, Span, InternedString, usize) -> P<Expr>
 {
     match *fields {
-        Unnamed(ref fields) => {
+        Unnamed(ref fields, is_tuple) => {
             let path_expr = cx.expr_path(outer_pat_path);
-            if fields.is_empty() {
+            if !is_tuple {
                 path_expr
             } else {
                 let fields = fields.iter()
diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs
index 9df3db938b1..449c1ff066b 100644
--- a/src/libsyntax_ext/deriving/default.rs
+++ b/src/libsyntax_ext/deriving/default.rs
@@ -57,8 +57,8 @@ fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructur
     return match *substr.fields {
         StaticStruct(_, ref summary) => {
             match *summary {
-                Unnamed(ref fields) => {
-                    if fields.is_empty() {
+                Unnamed(ref fields, is_tuple) => {
+                    if !is_tuple {
                         cx.expr_ident(trait_span, substr.type_ident)
                     } else {
                         let exprs = fields.iter().map(|sp| default_call(*sp)).collect();
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index cd49e7ec9d2..22e98fb213f 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -294,8 +294,8 @@ pub struct FieldInfo<'a> {
 
 /// Fields for a static method
 pub enum StaticFields {
-    /// Tuple structs/enum variants like this.
-    Unnamed(Vec<Span>),
+    /// Tuple and unit structs/enum variants like this.
+    Unnamed(Vec<Span>, bool /*is tuple*/),
     /// Normal structs/struct variants.
     Named(Vec<(Ident, Span)>),
 }
@@ -1470,7 +1470,7 @@ impl<'a> TraitDef<'a> {
             (_, false) => Named(named_idents),
             // empty structs
             _ if struct_def.is_struct() => Named(named_idents),
-            _ => Unnamed(just_spans),
+            _ => Unnamed(just_spans, struct_def.is_tuple()),
         }
     }
 
diff --git a/src/test/run-pass-fulldeps/empty-struct-braces-derive.rs b/src/test/run-pass-fulldeps/empty-struct-braces-derive.rs
index 8d19209208d..66ffff94333 100644
--- a/src/test/run-pass-fulldeps/empty-struct-braces-derive.rs
+++ b/src/test/run-pass-fulldeps/empty-struct-braces-derive.rs
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// `#[derive(Trait)]` works for empty structs/variants with braces
+// `#[derive(Trait)]` works for empty structs/variants with braces or parens.
 
+#![feature(relaxed_adts)]
 #![feature(rustc_private)]
 
 extern crate serialize as rustc_serialize;
@@ -19,10 +20,15 @@ extern crate serialize as rustc_serialize;
 struct S {}
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
+         Default, Debug, RustcEncodable, RustcDecodable)]
+struct Z();
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
          Debug, RustcEncodable, RustcDecodable)]
 enum E {
     V {},
     U,
+    W(),
 }
 
 fn main() {
@@ -34,6 +40,14 @@ fn main() {
     assert!(!(s < s1));
     assert_eq!(format!("{:?}", s), "S");
 
+    let z = Z();
+    let z1 = z;
+    let z2 = z.clone();
+    assert_eq!(z, z1);
+    assert_eq!(z, z2);
+    assert!(!(z < z1));
+    assert_eq!(format!("{:?}", z), "Z");
+
     let e = E::V {};
     let e1 = e;
     let e2 = e.clone();
@@ -41,4 +55,12 @@ fn main() {
     assert_eq!(e, e2);
     assert!(!(e < e1));
     assert_eq!(format!("{:?}", e), "V");
+
+    let e = E::W();
+    let e1 = e;
+    let e2 = e.clone();
+    assert_eq!(e, e1);
+    assert_eq!(e, e2);
+    assert!(!(e < e1));
+    assert_eq!(format!("{:?}", e), "W");
 }