]> git.proxmox.com Git - rustc.git/blobdiff - src/libsyntax_ext/deriving/generic/mod.rs
Imported Upstream version 1.8.0+dfsg1
[rustc.git] / src / libsyntax_ext / deriving / generic / mod.rs
index 3af701739b43119578978f292888df1c43147a79..c0237a5d29a4103dbf8e535ba9800cc474929fca 100644 (file)
@@ -193,9 +193,7 @@ use std::collections::HashSet;
 use std::vec;
 
 use syntax::abi::Abi;
-use syntax::abi;
-use syntax::ast;
-use syntax::ast::{EnumDef, Expr, Ident, Generics, VariantData};
+use syntax::ast::{self, EnumDef, Expr, Ident, Generics, VariantData, BinOpKind, PatKind};
 use syntax::ast_util;
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
@@ -302,7 +300,7 @@ pub enum StaticFields {
 
 /// A summary of the possible sets of fields.
 pub enum SubstructureFields<'a> {
-    Struct(Vec<FieldInfo<'a>>),
+    Struct(&'a ast::VariantData, Vec<FieldInfo<'a>>),
     /// Matching variants of the enum: variant index, ast::Variant,
     /// fields: the field name is only non-`None` in the case of a struct
     /// variant.
@@ -314,7 +312,7 @@ pub enum SubstructureFields<'a> {
     /// variants for the enum itself, and the third component is a list of
     /// `Ident`s bound to the variant index values for each of the actual
     /// input `Self` arguments.
-    EnumNonMatchingCollapsed(Vec<Ident>, &'a [P<ast::Variant>], &'a [Ident]),
+    EnumNonMatchingCollapsed(Vec<Ident>, &'a [ast::Variant], &'a [Ident]),
 
     /// A static method where `Self` is a struct.
     StaticStruct(&'a ast::VariantData, StaticFields),
@@ -356,7 +354,7 @@ fn find_type_parameters(ty: &ast::Ty, ty_param_names: &[ast::Name]) -> Vec<P<ast
     impl<'a> visit::Visitor<'a> for Visitor<'a> {
         fn visit_ty(&mut self, ty: &'a ast::Ty) {
             match ty.node {
-                ast::TyPath(_, ref path) if !path.global => {
+                ast::TyKind::Path(_, ref path) if !path.global => {
                     match path.segments.first() {
                         Some(segment) => {
                             if self.ty_param_names.contains(&segment.identifier.name) {
@@ -393,13 +391,13 @@ impl<'a> TraitDef<'a> {
         match *item {
             Annotatable::Item(ref item) => {
                 let newitem = match item.node {
-                    ast::ItemStruct(ref struct_def, ref generics) => {
+                    ast::ItemKind::Struct(ref struct_def, ref generics) => {
                         self.expand_struct_def(cx,
                                                &struct_def,
                                                item.ident,
                                                generics)
                     }
-                    ast::ItemEnum(ref enum_def, ref generics) => {
+                    ast::ItemKind::Enum(ref enum_def, ref generics) => {
                         self.expand_enum_def(cx,
                                              enum_def,
                                              &item.attrs,
@@ -468,23 +466,23 @@ impl<'a> TraitDef<'a> {
                            type_ident: Ident,
                            generics: &Generics,
                            field_tys: Vec<P<ast::Ty>>,
-                           methods: Vec<P<ast::ImplItem>>) -> P<ast::Item> {
+                           methods: Vec<ast::ImplItem>) -> P<ast::Item> {
         let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
 
         // Transform associated types from `deriving::ty::Ty` into `ast::ImplItem`
         let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| {
-            P(ast::ImplItem {
+            ast::ImplItem {
                 id: ast::DUMMY_NODE_ID,
                 span: self.span,
                 ident: ident,
-                vis: ast::Inherited,
+                vis: ast::Visibility::Inherited,
                 attrs: Vec::new(),
                 node: ast::ImplItemKind::Type(type_def.to_ty(cx,
                     self.span,
                     type_ident,
                     generics
                 )),
-            })
+            }
         });
 
         let Generics { mut lifetimes, ty_params, mut where_clause } =
@@ -555,11 +553,11 @@ impl<'a> TraitDef<'a> {
 
             let mut processed_field_types = HashSet::new();
             for field_ty in field_tys {
-                let tys = find_type_parameters(&*field_ty, &ty_param_names);
+                let tys = find_type_parameters(&field_ty, &ty_param_names);
 
                 for ty in tys {
                     // if we have already handled this type, skip it
-                    if let ast::TyPath(_, ref p) = ty.node {
+                    if let ast::TyKind::Path(_, ref p) = ty.node {
                         if p.segments.len() == 1
                             && ty_param_names.contains(&p.segments[0].identifier.name)
                             || processed_field_types.contains(&p.segments) {
@@ -619,7 +617,7 @@ impl<'a> TraitDef<'a> {
         // Just mark it now since we know that it'll end up used downstream
         attr::mark_used(&attr);
         let opt_trait_ref = Some(trait_ref);
-        let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&*self_type));
+        let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&self_type));
         let unused_qual = cx.attribute(
             self.span,
             cx.meta_list(self.span,
@@ -639,12 +637,12 @@ impl<'a> TraitDef<'a> {
             self.span,
             ident,
             a,
-            ast::ItemImpl(unsafety,
-                          ast::ImplPolarity::Positive,
-                          trait_generics,
-                          opt_trait_ref,
-                          self_type,
-                          methods.into_iter().chain(associated_types).collect()))
+            ast::ItemKind::Impl(unsafety,
+                                ast::ImplPolarity::Positive,
+                                trait_generics,
+                                opt_trait_ref,
+                                self_type,
+                                methods.into_iter().chain(associated_types).collect()))
     }
 
     fn expand_struct_def(&self,
@@ -682,7 +680,7 @@ impl<'a> TraitDef<'a> {
                                      self,
                                      type_ident,
                                      generics,
-                                     abi::Rust,
+                                     Abi::Rust,
                                      explicit_self,
                                      tys,
                                      body)
@@ -731,7 +729,7 @@ impl<'a> TraitDef<'a> {
                                      self,
                                      type_ident,
                                      generics,
-                                     abi::Rust,
+                                     Abi::Rust,
                                      explicit_self,
                                      tys,
                                      body)
@@ -750,17 +748,17 @@ fn find_repr_type_name(diagnostic: &Handler,
                 attr::ReprAny | attr::ReprPacked | attr::ReprSimd => continue,
                 attr::ReprExtern => "i32",
 
-                attr::ReprInt(_, attr::SignedInt(ast::TyIs)) => "isize",
-                attr::ReprInt(_, attr::SignedInt(ast::TyI8)) => "i8",
-                attr::ReprInt(_, attr::SignedInt(ast::TyI16)) => "i16",
-                attr::ReprInt(_, attr::SignedInt(ast::TyI32)) => "i32",
-                attr::ReprInt(_, attr::SignedInt(ast::TyI64)) => "i64",
-
-                attr::ReprInt(_, attr::UnsignedInt(ast::TyUs)) => "usize",
-                attr::ReprInt(_, attr::UnsignedInt(ast::TyU8)) => "u8",
-                attr::ReprInt(_, attr::UnsignedInt(ast::TyU16)) => "u16",
-                attr::ReprInt(_, attr::UnsignedInt(ast::TyU32)) => "u32",
-                attr::ReprInt(_, attr::UnsignedInt(ast::TyU64)) => "u64",
+                attr::ReprInt(_, attr::SignedInt(ast::IntTy::Is)) => "isize",
+                attr::ReprInt(_, attr::SignedInt(ast::IntTy::I8)) => "i8",
+                attr::ReprInt(_, attr::SignedInt(ast::IntTy::I16)) => "i16",
+                attr::ReprInt(_, attr::SignedInt(ast::IntTy::I32)) => "i32",
+                attr::ReprInt(_, attr::SignedInt(ast::IntTy::I64)) => "i64",
+
+                attr::ReprInt(_, attr::UnsignedInt(ast::UintTy::Us)) => "usize",
+                attr::ReprInt(_, attr::UnsignedInt(ast::UintTy::U8)) => "u8",
+                attr::ReprInt(_, attr::UnsignedInt(ast::UintTy::U16)) => "u16",
+                attr::ReprInt(_, attr::UnsignedInt(ast::UintTy::U32)) => "u32",
+                attr::ReprInt(_, attr::UnsignedInt(ast::UintTy::U64)) => "u64",
             }
         }
     }
@@ -823,7 +821,7 @@ impl<'a> MethodDef<'a> {
 
                 explicit_self
             }
-            None => codemap::respan(trait_.span, ast::SelfStatic),
+            None => codemap::respan(trait_.span, ast::SelfKind::Static),
         };
 
         for (i, ty) in self.args.iter().enumerate() {
@@ -859,14 +857,16 @@ impl<'a> MethodDef<'a> {
                      abi: Abi,
                      explicit_self: ast::ExplicitSelf,
                      arg_types: Vec<(Ident, P<ast::Ty>)> ,
-                     body: P<Expr>) -> P<ast::ImplItem> {
+                     body: P<Expr>) -> ast::ImplItem {
         // create the generics that aren't for Self
         let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
 
         let self_arg = match explicit_self.node {
-            ast::SelfStatic => None,
+            ast::SelfKind::Static => None,
             // creating fresh self id
-            _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable, special_idents::self_))
+            _ => Some(ast::Arg::new_self(trait_.span,
+                                         ast::Mutability::Immutable,
+                                         special_idents::self_))
         };
         let args = {
             let args = arg_types.into_iter().map(|(name, ty)| {
@@ -888,11 +888,11 @@ impl<'a> MethodDef<'a> {
         };
 
         // Create the method.
-        P(ast::ImplItem {
+        ast::ImplItem {
             id: ast::DUMMY_NODE_ID,
             attrs: self.attributes.clone(),
             span: trait_.span,
-            vis: ast::Inherited,
+            vis: ast::Visibility::Inherited,
             ident: method_ident,
             node: ast::ImplItemKind::Method(ast::MethodSig {
                 generics: fn_generics,
@@ -902,7 +902,7 @@ impl<'a> MethodDef<'a> {
                 constness: ast::Constness::NotConst,
                 decl: fn_decl
             }, body_block)
-        })
+        }
     }
 
     /// ```ignore
@@ -944,7 +944,7 @@ impl<'a> MethodDef<'a> {
                                              struct_def,
                                              &format!("__self_{}",
                                                      i),
-                                             ast::MutImmutable);
+                                             ast::Mutability::Immutable);
             patterns.push(pat);
             raw_fields.push(ident_expr);
         }
@@ -981,7 +981,7 @@ impl<'a> MethodDef<'a> {
             type_ident,
             self_args,
             nonself_args,
-            &Struct(fields));
+            &Struct(struct_def, fields));
 
         // make a series of nested matches, to destructure the
         // structs. This is actually right-to-left, but it shouldn't
@@ -1137,11 +1137,12 @@ impl<'a> MethodDef<'a> {
         let mut match_arms: Vec<ast::Arm> = variants.iter().enumerate()
             .map(|(index, variant)| {
                 let mk_self_pat = |cx: &mut ExtCtxt, self_arg_name: &str| {
-                    let (p, idents) = trait_.create_enum_variant_pattern(cx, type_ident,
-                                                                         &**variant,
-                                                                         self_arg_name,
-                                                                         ast::MutImmutable);
-                    (cx.pat(sp, ast::PatRegion(p, ast::MutImmutable)), idents)
+                    let (p, idents) = trait_.create_enum_variant_pattern(
+                        cx, type_ident,
+                        variant,
+                        self_arg_name,
+                        ast::Mutability::Immutable);
+                    (cx.pat(sp, PatKind::Ref(p, ast::Mutability::Immutable)), idents)
                 };
 
                 // A single arm has form (&VariantK, &VariantK, ...) => BodyK
@@ -1208,7 +1209,7 @@ impl<'a> MethodDef<'a> {
                 // Self arg, assuming all are instances of VariantK.
                 // Build up code associated with such a case.
                 let substructure = EnumMatching(index,
-                                                &**variant,
+                                                variant,
                                                 field_tuples);
                 let arm_expr = self.call_substructure_method(
                     cx, trait_, type_ident, &self_args[..], nonself_args,
@@ -1249,7 +1250,7 @@ impl<'a> MethodDef<'a> {
             // let __self2_vi = unsafe {
             //     std::intrinsics::discriminant_value(&__arg2) } as i32;
             // ```
-            let mut index_let_stmts: Vec<P<ast::Stmt>> = Vec::new();
+            let mut index_let_stmts: Vec<ast::Stmt> = Vec::new();
 
             //We also build an expression which checks whether all discriminants are equal
             // discriminant_test = __self0_vi == __self1_vi && __self0_vi == __self2_vi && ...
@@ -1267,7 +1268,7 @@ impl<'a> MethodDef<'a> {
                     stmts: vec![],
                     expr: Some(call),
                     id: ast::DUMMY_NODE_ID,
-                    rules: ast::UnsafeBlock(ast::CompilerGenerated),
+                    rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
                     span: sp }));
 
                 let target_ty = cx.ty_ident(sp, cx.ident_of(target_type_name));
@@ -1279,8 +1280,9 @@ impl<'a> MethodDef<'a> {
                     Some(first) => {
                         let first_expr = cx.expr_ident(sp, first);
                         let id = cx.expr_ident(sp, ident);
-                        let test = cx.expr_binary(sp, ast::BiEq, first_expr, id);
-                        discriminant_test = cx.expr_binary(sp, ast::BiAnd, discriminant_test, test)
+                        let test = cx.expr_binary(sp, BinOpKind::Eq, first_expr, id);
+                        discriminant_test = cx.expr_binary(sp, BinOpKind::And,
+                                                           discriminant_test, test)
                     }
                     None => {
                         first_ident = Some(ident);
@@ -1302,7 +1304,7 @@ impl<'a> MethodDef<'a> {
                 stmts: vec![],
                 expr: Some(call),
                 id: ast::DUMMY_NODE_ID,
-                rules: ast::UnsafeBlock(ast::CompilerGenerated),
+                rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated),
                 span: sp }));
             match_arms.push(cx.arm(sp, vec![cx.pat_wild(sp)], unreachable));
 
@@ -1312,7 +1314,7 @@ impl<'a> MethodDef<'a> {
             // expression; here add a layer of borrowing, turning
             // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
             let borrowed_self_args = self_args.move_map(|self_arg| cx.expr_addr_of(sp, self_arg));
-            let match_arg = cx.expr(sp, ast::ExprTup(borrowed_self_args));
+            let match_arg = cx.expr(sp, ast::ExprKind::Tup(borrowed_self_args));
 
             //Lastly we create an expression which branches on all discriminants being equal
             //  if discriminant_test {
@@ -1390,7 +1392,7 @@ impl<'a> MethodDef<'a> {
             // expression; here add a layer of borrowing, turning
             // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
             let borrowed_self_args = self_args.move_map(|self_arg| cx.expr_addr_of(sp, self_arg));
-            let match_arg = cx.expr(sp, ast::ExprTup(borrowed_self_args));
+            let match_arg = cx.expr(sp, ast::ExprKind::Tup(borrowed_self_args));
             cx.expr_match(sp, match_arg, match_arms)
         }
     }
@@ -1458,8 +1460,9 @@ impl<'a> TraitDef<'a> {
                                           fields in generic `derive`"),
             // named fields
             (_, false) => Named(named_idents),
-            // tuple structs (includes empty structs)
-            (_, _)     => Unnamed(just_spans)
+            // empty structs
+            _ if struct_def.is_struct() => Named(named_idents),
+            _ => Unnamed(just_spans),
         }
     }
 
@@ -1470,7 +1473,7 @@ impl<'a> TraitDef<'a> {
                           -> Vec<P<ast::Pat>> {
         field_paths.iter().map(|path| {
             cx.pat(path.span,
-                        ast::PatIdent(ast::BindingMode::ByRef(mutbl), (*path).clone(), None))
+                        PatKind::Ident(ast::BindingMode::ByRef(mutbl), (*path).clone(), None))
         }).collect()
     }
 
@@ -1484,7 +1487,11 @@ impl<'a> TraitDef<'a> {
                                                    P<Expr>,
                                                    &'a [ast::Attribute])>) {
         if struct_def.fields().is_empty() {
-            return (cx.pat_enum(self.span, struct_path, vec![]), vec![]);
+            if struct_def.is_struct() {
+                return (cx.pat_struct(self.span, struct_path, vec![]), vec![]);
+            } else {
+                return (cx.pat_enum(self.span, struct_path, vec![]), vec![]);
+            }
         }
 
         let mut paths = Vec::new();
@@ -1510,8 +1517,8 @@ impl<'a> TraitDef<'a> {
             };
             let ident = cx.ident_of(&format!("{}_{}", prefix, i));
             paths.push(codemap::Spanned{span: sp, node: ident});
-            let val = cx.expr(
-                sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident)))));
+            let val = cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident)));
+            let val = cx.expr(sp, ast::ExprKind::Paren(val));
             ident_expr.push((sp, opt_id, val, &struct_field.node.attrs[..]));
         }
 
@@ -1519,7 +1526,7 @@ impl<'a> TraitDef<'a> {
 
         // struct_type is definitely not Unknown, since struct_def.fields
         // must be nonempty to reach here
-        let pattern = if struct_type == Record {
+        let pattern = if struct_def.is_struct() {
             let field_pats = subpats.into_iter().zip(&ident_expr)
                                     .map(|(pat, &(_, id, _, _))| {
                 // id is guaranteed to be Some
@@ -1564,7 +1571,7 @@ pub fn cs_fold<F>(use_foldl: bool,
     F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
 {
     match *substructure.fields {
-        EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
+        EnumMatching(_, _, ref all_fields) | Struct(_, ref all_fields) => {
             if use_foldl {
                 all_fields.iter().fold(base, |old, field| {
                     f(cx,
@@ -1610,7 +1617,7 @@ pub fn cs_same_method<F>(f: F,
     F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>,
 {
     match *substructure.fields {
-        EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
+        EnumMatching(_, _, ref all_fields) | Struct(_, ref all_fields) => {
             // call self_n.method(other_1_n, other_2_n, ...)
             let called = all_fields.iter().map(|field| {
                 cx.expr_method_call(field.span,