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 @@ fn pat_ident_binding_mode(&self, } fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec>) -> P { 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(cx: &mut ExtCtxt, where F: FnMut(&mut ExtCtxt, Span, InternedString, usize) -> P { 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), + /// Tuple and unit structs/enum variants like this. + Unnamed(Vec, bool /*is tuple*/), /// Normal structs/struct variants. Named(Vec<(Ident, Span)>), } @@ -1470,7 +1470,7 @@ fn summarise_struct(&self, cx: &mut ExtCtxt, struct_def: &VariantData) -> Static (_, 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; @@ -18,11 +19,16 @@ Default, Debug, RustcEncodable, RustcDecodable)] 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"); }