]> git.proxmox.com Git - rustc.git/blobdiff - src/libsyntax_ext/deriving/generic/mod.rs
New upstream version 1.29.0+dfsg1
[rustc.git] / src / libsyntax_ext / deriving / generic / mod.rs
index 80f65957c39a2e3935c41ef99b961c2c083e50bd..e0f985c26c7a1cd9efd69bc3b09e3b0ab09afd80 100644 (file)
@@ -188,18 +188,16 @@ pub use self::StaticFields::*;
 pub use self::SubstructureFields::*;
 
 use std::cell::RefCell;
-use std::collections::HashSet;
+use std::iter;
 use std::vec;
 
 use rustc_target::spec::abi::Abi;
-use syntax::ast::{
-    self, BinOpKind, EnumDef, Expr, GenericParam, Generics, Ident, PatKind, VariantData
-};
-
+use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
+use syntax::ast::{VariantData, GenericParamKind, GenericArg};
 use syntax::attr;
 use syntax::ext::base::{Annotatable, ExtCtxt};
 use syntax::ext::build::AstBuilder;
-use syntax::codemap::{self, dummy_spanned, respan};
+use syntax::codemap::{self, respan};
 use syntax::util::move_map::MoveMap;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, keywords};
@@ -332,7 +330,7 @@ pub enum SubstructureFields<'a> {
 /// Combine the values of all the fields together. The last argument is
 /// all the fields of all the structures.
 pub type CombineSubstructureFunc<'a> =
-    Box<FnMut(&mut ExtCtxt, Span, &Substructure) -> P<Expr> + 'a>;
+    Box<dyn FnMut(&mut ExtCtxt, Span, &Substructure) -> P<Expr> + 'a>;
 
 /// Deal with non-matching enum variants.  The tuple is a list of
 /// identifiers (one for each `Self` argument, which could be any of the
@@ -340,7 +338,7 @@ pub type CombineSubstructureFunc<'a> =
 /// holding the variant index value for each of the `Self` arguments.  The
 /// last argument is all the non-`Self` args of the method being derived.
 pub type EnumNonMatchCollapsedFunc<'a> =
-    Box<FnMut(&mut ExtCtxt, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
+    Box<dyn FnMut(&mut ExtCtxt, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
 
 pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
                                 -> RefCell<CombineSubstructureFunc<'a>> {
@@ -400,7 +398,7 @@ impl<'a> TraitDef<'a> {
                   cx: &mut ExtCtxt,
                   mitem: &ast::MetaItem,
                   item: &'a Annotatable,
-                  push: &mut FnMut(Annotatable)) {
+                  push: &mut dyn FnMut(Annotatable)) {
         self.expand_ext(cx, mitem, item, push, false);
     }
 
@@ -408,7 +406,7 @@ impl<'a> TraitDef<'a> {
                       cx: &mut ExtCtxt,
                       mitem: &ast::MetaItem,
                       item: &'a Annotatable,
-                      push: &mut FnMut(Annotatable),
+                      push: &mut dyn FnMut(Annotatable),
                       from_scratch: bool) {
         match *item {
             Annotatable::Item(ref item) => {
@@ -424,7 +422,10 @@ impl<'a> TraitDef<'a> {
                     ast::ItemKind::Struct(_, ref generics) |
                     ast::ItemKind::Enum(_, ref generics) |
                     ast::ItemKind::Union(_, ref generics) => {
-                        !generics.params.iter().any(|p| p.is_type_param())
+                        !generics.params.iter().any(|param| match param.kind {
+                            ast::GenericParamKind::Type { .. } => true,
+                            _ => false,
+                        })
                     }
                     _ => {
                         // Non-ADT derive is an error, but it should have been
@@ -548,30 +549,25 @@ impl<'a> TraitDef<'a> {
             .to_generics(cx, self.span, type_ident, generics);
 
         // Create the generic parameters
-        params.extend(generics.params.iter().map(|param| {
-            match *param {
-                ref l @ GenericParam::Lifetime(_) => l.clone(),
-                GenericParam::Type(ref ty_param) => {
-                    // I don't think this can be moved out of the loop, since
-                    // a TyParamBound requires an ast id
-                    let mut bounds: Vec<_> =
-                        // extra restrictions on the generics parameters to the
-                        // type being derived upon
-                        self.additional_bounds.iter().map(|p| {
-                            cx.typarambound(p.to_path(cx, self.span,
-                                                        type_ident, generics))
-                        }).collect();
-
-                    // require the current trait
-                    bounds.push(cx.typarambound(trait_path.clone()));
-
-                    // also add in any bounds from the declaration
-                    for declared_bound in ty_param.bounds.iter() {
-                        bounds.push((*declared_bound).clone());
-                    }
+        params.extend(generics.params.iter().map(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => param.clone(),
+            GenericParamKind::Type { .. } => {
+                // I don't think this can be moved out of the loop, since
+                // a GenericBound requires an ast id
+                let mut bounds: Vec<_> =
+                    // extra restrictions on the generics parameters to the
+                    // type being derived upon
+                    self.additional_bounds.iter().map(|p| {
+                        cx.trait_bound(p.to_path(cx, self.span, type_ident, generics))
+                    }).chain(
+                        // require the current trait
+                        iter::once(cx.trait_bound(trait_path.clone()))
+                    ).chain(
+                        // also add in any bounds from the declaration
+                        param.bounds.iter().cloned()
+                    ).collect();
 
-                    GenericParam::Type(cx.typaram(self.span, ty_param.ident, vec![], bounds, None))
-                }
+                cx.typaram(self.span, param.ident, vec![], bounds, None)
             }
         }));
 
@@ -608,8 +604,8 @@ impl<'a> TraitDef<'a> {
             // Extra scope required here so ty_params goes out of scope before params is moved
 
             let mut ty_params = params.iter()
-                .filter_map(|param| match *param {
-                    ast::GenericParam::Type(ref t) => Some(t),
+                .filter_map(|param| match param.kind {
+                    ast::GenericParamKind::Type { .. } => Some(param),
                     _ => None,
                 })
                 .peekable();
@@ -619,7 +615,6 @@ impl<'a> TraitDef<'a> {
                     .map(|ty_param| ty_param.ident.name)
                     .collect();
 
-                let mut processed_field_types = HashSet::new();
                 for field_ty in field_tys {
                     let tys = find_type_parameters(&field_ty, &ty_param_names, self.span, cx);
 
@@ -627,21 +622,19 @@ impl<'a> TraitDef<'a> {
                         // if we have already handled this type, skip it
                         if let ast::TyKind::Path(_, ref p) = ty.node {
                             if p.segments.len() == 1 &&
-                            ty_param_names.contains(&p.segments[0].ident.name) ||
-                            processed_field_types.contains(&p.segments) {
+                               ty_param_names.contains(&p.segments[0].ident.name) {
                                 continue;
                             };
-                            processed_field_types.insert(p.segments.clone());
                         }
                         let mut bounds: Vec<_> = self.additional_bounds
                             .iter()
                             .map(|p| {
-                                cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
+                                cx.trait_bound(p.to_path(cx, self.span, type_ident, generics))
                             })
                             .collect();
 
                         // require the current trait
-                        bounds.push(cx.typarambound(trait_path.clone()));
+                        bounds.push(cx.trait_bound(trait_path.clone()));
 
                         let predicate = ast::WhereBoundPredicate {
                             span: self.span,
@@ -666,31 +659,18 @@ impl<'a> TraitDef<'a> {
         // Create the reference to the trait.
         let trait_ref = cx.trait_ref(trait_path);
 
-        // Create the type parameters on the `self` path.
-        let self_ty_params = generics.params
-            .iter()
-            .filter_map(|param| match *param {
-                GenericParam::Type(ref ty_param)
-                    => Some(cx.ty_ident(self.span, ty_param.ident)),
-                _ => None,
-            })
-            .collect();
-
-        let self_lifetimes: Vec<ast::Lifetime> = generics.params
-            .iter()
-            .filter_map(|param| match *param {
-                GenericParam::Lifetime(ref ld) => Some(ld.lifetime),
-                _ => None,
-            })
-            .collect();
+        let self_params: Vec<_> = generics.params.iter().map(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => {
+                GenericArg::Lifetime(cx.lifetime(self.span, param.ident))
+            }
+            GenericParamKind::Type { .. } => {
+                GenericArg::Type(cx.ty_ident(self.span, param.ident))
+            }
+        }).collect();
 
         // Create the type of `self`.
-        let self_type = cx.ty_path(cx.path_all(self.span,
-                                               false,
-                                               vec![type_ident],
-                                               self_lifetimes,
-                                               self_ty_params,
-                                               Vec::new()));
+        let path = cx.path_all(self.span, false, vec![type_ident], self_params, vec![]);
+        let self_type = cx.ty_path(path);
 
         let attr = cx.attribute(self.span,
                                 cx.meta_word(self.span,
@@ -928,7 +908,7 @@ impl<'a> MethodDef<'a> {
                 Self_ if nonstatic => {
                     self_args.push(arg_expr);
                 }
-                Ptr(ref ty, _) if **ty == Self_ && nonstatic => {
+                Ptr(ref ty, _) if (if let Self_ = **ty { true } else { false }) && nonstatic => {
                     self_args.push(cx.expr_deref(trait_.span, arg_expr))
                 }
                 _ => {
@@ -986,10 +966,10 @@ impl<'a> MethodDef<'a> {
             defaultness: ast::Defaultness::Final,
             ident: method_ident,
             node: ast::ImplItemKind::Method(ast::MethodSig {
-                                                abi,
-                                                unsafety,
-                                                constness:
-                                                    dummy_spanned(ast::Constness::NotConst),
+                                                header: ast::FnHeader {
+                                                    unsafety, abi,
+                                                    ..ast::FnHeader::default()
+                                                },
                                                 decl: fn_decl,
                                             },
                                             body_block),