about summary refs log tree commit diff
path: root/src/libsyntax_ext/deriving/generic
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-12-29 16:39:31 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-12-30 19:18:16 +0300
commitb683de4ad79242fdeebcae2afefb72c1530babe9 (patch)
treee46daf86fae68f2246b1dd80500f4a504d452b84 /src/libsyntax_ext/deriving/generic
parent0fb43801368ae8b5931583f813071120bed55c35 (diff)
downloadrust-b683de4ad79242fdeebcae2afefb72c1530babe9.tar.gz
rust-b683de4ad79242fdeebcae2afefb72c1530babe9.zip
Rename directories for some crates from `syntax_x` to `rustc_x`
`syntax_expand` -> `rustc_expand`
`syntax_pos` -> `rustc_span`
`syntax_ext` -> `rustc_builtin_macros`
Diffstat (limited to 'src/libsyntax_ext/deriving/generic')
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs1812
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs283
2 files changed, 0 insertions, 2095 deletions
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
deleted file mode 100644
index 7d7b73ebb42..00000000000
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ /dev/null
@@ -1,1812 +0,0 @@
-//! Some code that abstracts away much of the boilerplate of writing
-//! `derive` instances for traits. Among other things it manages getting
-//! access to the fields of the 4 different sorts of structs and enum
-//! variants, as well as creating the method and impl ast instances.
-//!
-//! Supported features (fairly exhaustive):
-//!
-//! - Methods taking any number of parameters of any type, and returning
-//!   any type, other than vectors, bottom and closures.
-//! - Generating `impl`s for types with type parameters and lifetimes
-//!   (e.g., `Option<T>`), the parameters are automatically given the
-//!   current trait as a bound. (This includes separate type parameters
-//!   and lifetimes for methods.)
-//! - Additional bounds on the type parameters (`TraitDef.additional_bounds`)
-//!
-//! The most important thing for implementors is the `Substructure` and
-//! `SubstructureFields` objects. The latter groups 5 possibilities of the
-//! arguments:
-//!
-//! - `Struct`, when `Self` is a struct (including tuple structs, e.g
-//!   `struct T(i32, char)`).
-//! - `EnumMatching`, when `Self` is an enum and all the arguments are the
-//!   same variant of the enum (e.g., `Some(1)`, `Some(3)` and `Some(4)`)
-//! - `EnumNonMatchingCollapsed` when `Self` is an enum and the arguments
-//!   are not the same variant (e.g., `None`, `Some(1)` and `None`).
-//! - `StaticEnum` and `StaticStruct` for static methods, where the type
-//!   being derived upon is either an enum or struct respectively. (Any
-//!   argument with type Self is just grouped among the non-self
-//!   arguments.)
-//!
-//! In the first two cases, the values from the corresponding fields in
-//! all the arguments are grouped together. For `EnumNonMatchingCollapsed`
-//! this isn't possible (different variants have different fields), so the
-//! fields are inaccessible. (Previous versions of the deriving infrastructure
-//! had a way to expand into code that could access them, at the cost of
-//! generating exponential amounts of code; see issue #15375). There are no
-//! fields with values in the static cases, so these are treated entirely
-//! differently.
-//!
-//! The non-static cases have `Option<ident>` in several places associated
-//! with field `expr`s. This represents the name of the field it is
-//! associated with. It is only not `None` when the associated field has
-//! an identifier in the source code. For example, the `x`s in the
-//! following snippet
-//!
-//! ```rust
-//! # #![allow(dead_code)]
-//! struct A { x : i32 }
-//!
-//! struct B(i32);
-//!
-//! enum C {
-//!     C0(i32),
-//!     C1 { x: i32 }
-//! }
-//! ```
-//!
-//! The `i32`s in `B` and `C0` don't have an identifier, so the
-//! `Option<ident>`s would be `None` for them.
-//!
-//! In the static cases, the structure is summarized, either into the just
-//! spans of the fields or a list of spans and the field idents (for tuple
-//! structs and record structs, respectively), or a list of these, for
-//! enums (one for each variant). For empty struct and empty enum
-//! variants, it is represented as a count of 0.
-//!
-//! # "`cs`" functions
-//!
-//! The `cs_...` functions ("combine substructure) are designed to
-//! make life easier by providing some pre-made recipes for common
-//! threads; mostly calling the function being derived on all the
-//! arguments and then combining them back together in some way (or
-//! letting the user chose that). They are not meant to be the only
-//! way to handle the structures that this code creates.
-//!
-//! # Examples
-//!
-//! The following simplified `PartialEq` is used for in-code examples:
-//!
-//! ```rust
-//! trait PartialEq {
-//!     fn eq(&self, other: &Self) -> bool;
-//! }
-//! impl PartialEq for i32 {
-//!     fn eq(&self, other: &i32) -> bool {
-//!         *self == *other
-//!     }
-//! }
-//! ```
-//!
-//! Some examples of the values of `SubstructureFields` follow, using the
-//! above `PartialEq`, `A`, `B` and `C`.
-//!
-//! ## Structs
-//!
-//! When generating the `expr` for the `A` impl, the `SubstructureFields` is
-//!
-//! ```{.text}
-//! Struct(vec![FieldInfo {
-//!            span: <span of x>
-//!            name: Some(<ident of x>),
-//!            self_: <expr for &self.x>,
-//!            other: vec![<expr for &other.x]
-//!          }])
-//! ```
-//!
-//! For the `B` impl, called with `B(a)` and `B(b)`,
-//!
-//! ```{.text}
-//! Struct(vec![FieldInfo {
-//!           span: <span of `i32`>,
-//!           name: None,
-//!           self_: <expr for &a>
-//!           other: vec![<expr for &b>]
-//!          }])
-//! ```
-//!
-//! ## Enums
-//!
-//! When generating the `expr` for a call with `self == C0(a)` and `other
-//! == C0(b)`, the SubstructureFields is
-//!
-//! ```{.text}
-//! EnumMatching(0, <ast::Variant for C0>,
-//!              vec![FieldInfo {
-//!                 span: <span of i32>
-//!                 name: None,
-//!                 self_: <expr for &a>,
-//!                 other: vec![<expr for &b>]
-//!               }])
-//! ```
-//!
-//! For `C1 {x}` and `C1 {x}`,
-//!
-//! ```{.text}
-//! EnumMatching(1, <ast::Variant for C1>,
-//!              vec![FieldInfo {
-//!                 span: <span of x>
-//!                 name: Some(<ident of x>),
-//!                 self_: <expr for &self.x>,
-//!                 other: vec![<expr for &other.x>]
-//!                }])
-//! ```
-//!
-//! For `C0(a)` and `C1 {x}` ,
-//!
-//! ```{.text}
-//! EnumNonMatchingCollapsed(
-//!     vec![<ident of self>, <ident of __arg_1>],
-//!     &[<ast::Variant for C0>, <ast::Variant for C1>],
-//!     &[<ident for self index value>, <ident of __arg_1 index value>])
-//! ```
-//!
-//! It is the same for when the arguments are flipped to `C1 {x}` and
-//! `C0(a)`; the only difference is what the values of the identifiers
-//! <ident for self index value> and <ident of __arg_1 index value> will
-//! be in the generated code.
-//!
-//! `EnumNonMatchingCollapsed` deliberately provides far less information
-//! than is generally available for a given pair of variants; see #15375
-//! for discussion.
-//!
-//! ## Static
-//!
-//! A static method on the types above would result in,
-//!
-//! ```{.text}
-//! StaticStruct(<ast::VariantData of A>, Named(vec![(<ident of x>, <span of x>)]))
-//!
-//! StaticStruct(<ast::VariantData of B>, Unnamed(vec![<span of x>]))
-//!
-//! StaticEnum(<ast::EnumDef of C>,
-//!            vec![(<ident of C0>, <span of C0>, Unnamed(vec![<span of i32>])),
-//!                 (<ident of C1>, <span of C1>, Named(vec![(<ident of x>, <span of x>)]))])
-//! ```
-
-pub use StaticFields::*;
-pub use SubstructureFields::*;
-
-use std::cell::RefCell;
-use std::iter;
-use std::vec;
-
-use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
-use syntax::ast::{GenericArg, GenericParamKind, VariantData};
-use syntax::attr;
-use syntax::ptr::P;
-use syntax::sess::ParseSess;
-use syntax::source_map::respan;
-use syntax::symbol::{kw, sym, Symbol};
-use syntax::util::map_in_place::MapInPlace;
-use syntax_expand::base::{Annotatable, ExtCtxt};
-use syntax_pos::Span;
-
-use ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty};
-
-use crate::deriving;
-
-pub mod ty;
-
-pub struct TraitDef<'a> {
-    /// The span for the current #[derive(Foo)] header.
-    pub span: Span,
-
-    pub attributes: Vec<ast::Attribute>,
-
-    /// Path of the trait, including any type parameters
-    pub path: Path<'a>,
-
-    /// Additional bounds required of any type parameters of the type,
-    /// other than the current trait
-    pub additional_bounds: Vec<Ty<'a>>,
-
-    /// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
-    pub generics: LifetimeBounds<'a>,
-
-    /// Is it an `unsafe` trait?
-    pub is_unsafe: bool,
-
-    /// Can this trait be derived for unions?
-    pub supports_unions: bool,
-
-    pub methods: Vec<MethodDef<'a>>,
-
-    pub associated_types: Vec<(ast::Ident, Ty<'a>)>,
-}
-
-pub struct MethodDef<'a> {
-    /// name of the method
-    pub name: &'a str,
-    /// List of generics, e.g., `R: rand::Rng`
-    pub generics: LifetimeBounds<'a>,
-
-    /// Whether there is a self argument (outer Option) i.e., whether
-    /// this is a static function, and whether it is a pointer (inner
-    /// Option)
-    pub explicit_self: Option<Option<PtrTy>>,
-
-    /// Arguments other than the self argument
-    pub args: Vec<(Ty<'a>, &'a str)>,
-
-    /// Returns type
-    pub ret_ty: Ty<'a>,
-
-    pub attributes: Vec<ast::Attribute>,
-
-    // Is it an `unsafe fn`?
-    pub is_unsafe: bool,
-
-    /// Can we combine fieldless variants for enums into a single match arm?
-    pub unify_fieldless_variants: bool,
-
-    pub combine_substructure: RefCell<CombineSubstructureFunc<'a>>,
-}
-
-/// All the data about the data structure/method being derived upon.
-pub struct Substructure<'a> {
-    /// ident of self
-    pub type_ident: Ident,
-    /// ident of the method
-    pub method_ident: Ident,
-    /// dereferenced access to any `Self_` or `Ptr(Self_, _)` arguments
-    pub self_args: &'a [P<Expr>],
-    /// verbatim access to any other arguments
-    pub nonself_args: &'a [P<Expr>],
-    pub fields: &'a SubstructureFields<'a>,
-}
-
-/// Summary of the relevant parts of a struct/enum field.
-pub struct FieldInfo<'a> {
-    pub span: Span,
-    /// None for tuple structs/normal enum variants, Some for normal
-    /// structs/struct enum variants.
-    pub name: Option<Ident>,
-    /// The expression corresponding to this field of `self`
-    /// (specifically, a reference to it).
-    pub self_: P<Expr>,
-    /// The expressions corresponding to references to this field in
-    /// the other `Self` arguments.
-    pub other: Vec<P<Expr>>,
-    /// The attributes on the field
-    pub attrs: &'a [ast::Attribute],
-}
-
-/// Fields for a static method
-pub enum StaticFields {
-    /// Tuple and unit structs/enum variants like this.
-    Unnamed(Vec<Span>, bool /*is tuple*/),
-    /// Normal structs/struct variants.
-    Named(Vec<(Ident, Span)>),
-}
-
-/// A summary of the possible sets of fields.
-pub enum SubstructureFields<'a> {
-    Struct(&'a ast::VariantData, Vec<FieldInfo<'a>>),
-    /// Matching variants of the enum: variant index, variant count, ast::Variant,
-    /// fields: the field name is only non-`None` in the case of a struct
-    /// variant.
-    EnumMatching(usize, usize, &'a ast::Variant, Vec<FieldInfo<'a>>),
-
-    /// Non-matching variants of the enum, but with all state hidden from
-    /// the consequent code. The first component holds `Ident`s for all of
-    /// the `Self` arguments; the second component is a slice of all of the
-    /// 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 [ast::Variant], &'a [Ident]),
-
-    /// A static method where `Self` is a struct.
-    StaticStruct(&'a ast::VariantData, StaticFields),
-    /// A static method where `Self` is an enum.
-    StaticEnum(&'a ast::EnumDef, Vec<(Ident, Span, StaticFields)>),
-}
-
-/// Combine the values of all the fields together. The last argument is
-/// all the fields of all the structures.
-pub type CombineSubstructureFunc<'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
-/// variants since they have been collapsed together) and the identifiers
-/// 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<dyn FnMut(&mut ExtCtxt<'_>, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
-
-pub fn combine_substructure(
-    f: CombineSubstructureFunc<'_>,
-) -> RefCell<CombineSubstructureFunc<'_>> {
-    RefCell::new(f)
-}
-
-/// This method helps to extract all the type parameters referenced from a
-/// type. For a type parameter `<T>`, it looks for either a `TyPath` that
-/// is not global and starts with `T`, or a `TyQPath`.
-fn find_type_parameters(
-    ty: &ast::Ty,
-    ty_param_names: &[ast::Name],
-    cx: &ExtCtxt<'_>,
-) -> Vec<P<ast::Ty>> {
-    use syntax::visit;
-
-    struct Visitor<'a, 'b> {
-        cx: &'a ExtCtxt<'b>,
-        ty_param_names: &'a [ast::Name],
-        types: Vec<P<ast::Ty>>,
-    }
-
-    impl<'a, 'b> visit::Visitor<'a> for Visitor<'a, 'b> {
-        fn visit_ty(&mut self, ty: &'a ast::Ty) {
-            if let ast::TyKind::Path(_, ref path) = ty.kind {
-                if let Some(segment) = path.segments.first() {
-                    if self.ty_param_names.contains(&segment.ident.name) {
-                        self.types.push(P(ty.clone()));
-                    }
-                }
-            }
-
-            visit::walk_ty(self, ty)
-        }
-
-        fn visit_mac(&mut self, mac: &ast::Mac) {
-            self.cx.span_err(mac.span(), "`derive` cannot be used on items with type macros");
-        }
-    }
-
-    let mut visitor = Visitor { cx, ty_param_names, types: Vec::new() };
-    visit::Visitor::visit_ty(&mut visitor, ty);
-
-    visitor.types
-}
-
-impl<'a> TraitDef<'a> {
-    pub fn expand(
-        self,
-        cx: &mut ExtCtxt<'_>,
-        mitem: &ast::MetaItem,
-        item: &'a Annotatable,
-        push: &mut dyn FnMut(Annotatable),
-    ) {
-        self.expand_ext(cx, mitem, item, push, false);
-    }
-
-    pub fn expand_ext(
-        self,
-        cx: &mut ExtCtxt<'_>,
-        mitem: &ast::MetaItem,
-        item: &'a Annotatable,
-        push: &mut dyn FnMut(Annotatable),
-        from_scratch: bool,
-    ) {
-        match *item {
-            Annotatable::Item(ref item) => {
-                let is_packed = item.attrs.iter().any(|attr| {
-                    for r in attr::find_repr_attrs(&cx.parse_sess, attr) {
-                        if let attr::ReprPacked(_) = r {
-                            return true;
-                        }
-                    }
-                    false
-                });
-                let has_no_type_params = match item.kind {
-                    ast::ItemKind::Struct(_, ref generics)
-                    | ast::ItemKind::Enum(_, ref generics)
-                    | ast::ItemKind::Union(_, ref generics) => {
-                        !generics.params.iter().any(|param| match param.kind {
-                            ast::GenericParamKind::Type { .. } => true,
-                            _ => false,
-                        })
-                    }
-                    _ => {
-                        // Non-ADT derive is an error, but it should have been
-                        // set earlier; see
-                        // libsyntax_expand/expand.rs:MacroExpander::fully_expand_fragment()
-                        // libsyntax_expand/base.rs:Annotatable::derive_allowed()
-                        return;
-                    }
-                };
-                let container_id = cx.current_expansion.id.expn_data().parent;
-                let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id);
-                let use_temporaries = is_packed && always_copy;
-
-                let newitem = match item.kind {
-                    ast::ItemKind::Struct(ref struct_def, ref generics) => self.expand_struct_def(
-                        cx,
-                        &struct_def,
-                        item.ident,
-                        generics,
-                        from_scratch,
-                        use_temporaries,
-                    ),
-                    ast::ItemKind::Enum(ref enum_def, ref generics) => {
-                        // We ignore `use_temporaries` here, because
-                        // `repr(packed)` enums cause an error later on.
-                        //
-                        // This can only cause further compilation errors
-                        // downstream in blatantly illegal code, so it
-                        // is fine.
-                        self.expand_enum_def(
-                            cx,
-                            enum_def,
-                            &item.attrs,
-                            item.ident,
-                            generics,
-                            from_scratch,
-                        )
-                    }
-                    ast::ItemKind::Union(ref struct_def, ref generics) => {
-                        if self.supports_unions {
-                            self.expand_struct_def(
-                                cx,
-                                &struct_def,
-                                item.ident,
-                                generics,
-                                from_scratch,
-                                use_temporaries,
-                            )
-                        } else {
-                            cx.span_err(mitem.span, "this trait cannot be derived for unions");
-                            return;
-                        }
-                    }
-                    _ => unreachable!(),
-                };
-                // Keep the lint attributes of the previous item to control how the
-                // generated implementations are linted
-                let mut attrs = newitem.attrs.clone();
-                attrs.extend(
-                    item.attrs
-                        .iter()
-                        .filter(|a| {
-                            [
-                                sym::allow,
-                                sym::warn,
-                                sym::deny,
-                                sym::forbid,
-                                sym::stable,
-                                sym::unstable,
-                            ]
-                            .contains(&a.name_or_empty())
-                        })
-                        .cloned(),
-                );
-                push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() })))
-            }
-            _ => {
-                // Non-Item derive is an error, but it should have been
-                // set earlier; see
-                // libsyntax_expand/expand.rs:MacroExpander::fully_expand_fragment()
-                // libsyntax_expand/base.rs:Annotatable::derive_allowed()
-                return;
-            }
-        }
-    }
-
-    /// Given that we are deriving a trait `DerivedTrait` for a type like:
-    ///
-    /// ```ignore (only-for-syntax-highlight)
-    /// struct Struct<'a, ..., 'z, A, B: DeclaredTrait, C, ..., Z> where C: WhereTrait {
-    ///     a: A,
-    ///     b: B::Item,
-    ///     b1: <B as DeclaredTrait>::Item,
-    ///     c1: <C as WhereTrait>::Item,
-    ///     c2: Option<<C as WhereTrait>::Item>,
-    ///     ...
-    /// }
-    /// ```
-    ///
-    /// create an impl like:
-    ///
-    /// ```ignore (only-for-syntax-highlight)
-    /// impl<'a, ..., 'z, A, B: DeclaredTrait, C, ... Z> where
-    ///     C:                       WhereTrait,
-    ///     A: DerivedTrait + B1 + ... + BN,
-    ///     B: DerivedTrait + B1 + ... + BN,
-    ///     C: DerivedTrait + B1 + ... + BN,
-    ///     B::Item:                 DerivedTrait + B1 + ... + BN,
-    ///     <C as WhereTrait>::Item: DerivedTrait + B1 + ... + BN,
-    ///     ...
-    /// {
-    ///     ...
-    /// }
-    /// ```
-    ///
-    /// where B1, ..., BN are the bounds given by `bounds_paths`.'. Z is a phantom type, and
-    /// therefore does not get bound by the derived trait.
-    fn create_derived_impl(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        type_ident: Ident,
-        generics: &Generics,
-        field_tys: Vec<P<ast::Ty>>,
-        methods: Vec<ast::AssocItem>,
-    ) -> 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::AssocItem`
-        let associated_types =
-            self.associated_types.iter().map(|&(ident, ref type_def)| ast::AssocItem {
-                id: ast::DUMMY_NODE_ID,
-                span: self.span,
-                ident,
-                vis: respan(self.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
-                defaultness: ast::Defaultness::Final,
-                attrs: Vec::new(),
-                generics: Generics::default(),
-                kind: ast::AssocItemKind::TyAlias(
-                    Vec::new(),
-                    Some(type_def.to_ty(cx, self.span, type_ident, generics)),
-                ),
-                tokens: None,
-            });
-
-        let Generics { mut params, mut where_clause, span } =
-            self.generics.to_generics(cx, self.span, type_ident, generics);
-
-        // Create the generic parameters
-        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 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();
-
-                cx.typaram(self.span, param.ident, vec![], bounds, None)
-            }
-            GenericParamKind::Const { .. } => param.clone(),
-        }));
-
-        // and similarly for where clauses
-        where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
-            match *clause {
-                ast::WherePredicate::BoundPredicate(ref wb) => {
-                    ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                        span: self.span,
-                        bound_generic_params: wb.bound_generic_params.clone(),
-                        bounded_ty: wb.bounded_ty.clone(),
-                        bounds: wb.bounds.iter().cloned().collect(),
-                    })
-                }
-                ast::WherePredicate::RegionPredicate(ref rb) => {
-                    ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
-                        span: self.span,
-                        lifetime: rb.lifetime,
-                        bounds: rb.bounds.iter().cloned().collect(),
-                    })
-                }
-                ast::WherePredicate::EqPredicate(ref we) => {
-                    ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
-                        id: ast::DUMMY_NODE_ID,
-                        span: self.span,
-                        lhs_ty: we.lhs_ty.clone(),
-                        rhs_ty: we.rhs_ty.clone(),
-                    })
-                }
-            }
-        }));
-
-        {
-            // 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.kind {
-                    ast::GenericParamKind::Type { .. } => Some(param),
-                    _ => None,
-                })
-                .peekable();
-
-            if ty_params.peek().is_some() {
-                let ty_param_names: Vec<ast::Name> =
-                    ty_params.map(|ty_param| ty_param.ident.name).collect();
-
-                for field_ty in field_tys {
-                    let tys = find_type_parameters(&field_ty, &ty_param_names, cx);
-
-                    for ty in tys {
-                        // if we have already handled this type, skip it
-                        if let ast::TyKind::Path(_, ref p) = ty.kind {
-                            if p.segments.len() == 1
-                                && ty_param_names.contains(&p.segments[0].ident.name)
-                            {
-                                continue;
-                            };
-                        }
-                        let mut bounds: Vec<_> = self
-                            .additional_bounds
-                            .iter()
-                            .map(|p| cx.trait_bound(p.to_path(cx, self.span, type_ident, generics)))
-                            .collect();
-
-                        // require the current trait
-                        bounds.push(cx.trait_bound(trait_path.clone()));
-
-                        let predicate = ast::WhereBoundPredicate {
-                            span: self.span,
-                            bound_generic_params: Vec::new(),
-                            bounded_ty: ty,
-                            bounds,
-                        };
-
-                        let predicate = ast::WherePredicate::BoundPredicate(predicate);
-                        where_clause.predicates.push(predicate);
-                    }
-                }
-            }
-        }
-
-        let trait_generics = Generics { params, where_clause, span };
-
-        // Create the reference to the trait.
-        let trait_ref = cx.trait_ref(trait_path);
-
-        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))
-                }
-                GenericParamKind::Const { .. } => {
-                    GenericArg::Const(cx.const_ident(self.span, param.ident))
-                }
-            })
-            .collect();
-
-        // Create the type of `self`.
-        let path = cx.path_all(self.span, false, vec![type_ident], self_params);
-        let self_type = cx.ty_path(path);
-
-        let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
-        // 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 unused_qual = {
-            let word = syntax::attr::mk_nested_word_item(Ident::new(
-                Symbol::intern("unused_qualifications"),
-                self.span,
-            ));
-            let list = syntax::attr::mk_list_item(Ident::new(sym::allow, self.span), vec![word]);
-            cx.attribute(list)
-        };
-
-        let mut a = vec![attr, unused_qual];
-        a.extend(self.attributes.iter().cloned());
-
-        let unsafety = if self.is_unsafe { ast::Unsafety::Unsafe } else { ast::Unsafety::Normal };
-
-        cx.item(
-            self.span,
-            Ident::invalid(),
-            a,
-            ast::ItemKind::Impl(
-                unsafety,
-                ast::ImplPolarity::Positive,
-                ast::Defaultness::Final,
-                trait_generics,
-                opt_trait_ref,
-                self_type,
-                methods.into_iter().chain(associated_types).collect(),
-            ),
-        )
-    }
-
-    fn expand_struct_def(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        struct_def: &'a VariantData,
-        type_ident: Ident,
-        generics: &Generics,
-        from_scratch: bool,
-        use_temporaries: bool,
-    ) -> P<ast::Item> {
-        let field_tys: Vec<P<ast::Ty>> =
-            struct_def.fields().iter().map(|field| field.ty.clone()).collect();
-
-        let methods = self
-            .methods
-            .iter()
-            .map(|method_def| {
-                let (explicit_self, self_args, nonself_args, tys) =
-                    method_def.split_self_nonself_args(cx, self, type_ident, generics);
-
-                let body = if from_scratch || method_def.is_static() {
-                    method_def.expand_static_struct_method_body(
-                        cx,
-                        self,
-                        struct_def,
-                        type_ident,
-                        &self_args[..],
-                        &nonself_args[..],
-                    )
-                } else {
-                    method_def.expand_struct_method_body(
-                        cx,
-                        self,
-                        struct_def,
-                        type_ident,
-                        &self_args[..],
-                        &nonself_args[..],
-                        use_temporaries,
-                    )
-                };
-
-                method_def.create_method(cx, self, type_ident, generics, explicit_self, tys, body)
-            })
-            .collect();
-
-        self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
-    }
-
-    fn expand_enum_def(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        enum_def: &'a EnumDef,
-        type_attrs: &[ast::Attribute],
-        type_ident: Ident,
-        generics: &Generics,
-        from_scratch: bool,
-    ) -> P<ast::Item> {
-        let mut field_tys = Vec::new();
-
-        for variant in &enum_def.variants {
-            field_tys.extend(variant.data.fields().iter().map(|field| field.ty.clone()));
-        }
-
-        let methods = self
-            .methods
-            .iter()
-            .map(|method_def| {
-                let (explicit_self, self_args, nonself_args, tys) =
-                    method_def.split_self_nonself_args(cx, self, type_ident, generics);
-
-                let body = if from_scratch || method_def.is_static() {
-                    method_def.expand_static_enum_method_body(
-                        cx,
-                        self,
-                        enum_def,
-                        type_ident,
-                        &self_args[..],
-                        &nonself_args[..],
-                    )
-                } else {
-                    method_def.expand_enum_method_body(
-                        cx,
-                        self,
-                        enum_def,
-                        type_attrs,
-                        type_ident,
-                        self_args,
-                        &nonself_args[..],
-                    )
-                };
-
-                method_def.create_method(cx, self, type_ident, generics, explicit_self, tys, body)
-            })
-            .collect();
-
-        self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
-    }
-}
-
-fn find_repr_type_name(sess: &ParseSess, type_attrs: &[ast::Attribute]) -> &'static str {
-    let mut repr_type_name = "isize";
-    for a in type_attrs {
-        for r in &attr::find_repr_attrs(sess, a) {
-            repr_type_name = match *r {
-                attr::ReprPacked(_)
-                | attr::ReprSimd
-                | attr::ReprAlign(_)
-                | attr::ReprTransparent => continue,
-
-                attr::ReprC => "i32",
-
-                attr::ReprInt(attr::SignedInt(ast::IntTy::Isize)) => "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::SignedInt(ast::IntTy::I128)) => "i128",
-
-                attr::ReprInt(attr::UnsignedInt(ast::UintTy::Usize)) => "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",
-                attr::ReprInt(attr::UnsignedInt(ast::UintTy::U128)) => "u128",
-            }
-        }
-    }
-    repr_type_name
-}
-
-impl<'a> MethodDef<'a> {
-    fn call_substructure_method(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'_>,
-        type_ident: Ident,
-        self_args: &[P<Expr>],
-        nonself_args: &[P<Expr>],
-        fields: &SubstructureFields<'_>,
-    ) -> P<Expr> {
-        let substructure = Substructure {
-            type_ident,
-            method_ident: cx.ident_of(self.name, trait_.span),
-            self_args,
-            nonself_args,
-            fields,
-        };
-        let mut f = self.combine_substructure.borrow_mut();
-        let f: &mut CombineSubstructureFunc<'_> = &mut *f;
-        f(cx, trait_.span, &substructure)
-    }
-
-    fn get_ret_ty(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'_>,
-        generics: &Generics,
-        type_ident: Ident,
-    ) -> P<ast::Ty> {
-        self.ret_ty.to_ty(cx, trait_.span, type_ident, generics)
-    }
-
-    fn is_static(&self) -> bool {
-        self.explicit_self.is_none()
-    }
-
-    fn split_self_nonself_args(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'_>,
-        type_ident: Ident,
-        generics: &Generics,
-    ) -> (Option<ast::ExplicitSelf>, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) {
-        let mut self_args = Vec::new();
-        let mut nonself_args = Vec::new();
-        let mut arg_tys = Vec::new();
-        let mut nonstatic = false;
-
-        let ast_explicit_self = self.explicit_self.as_ref().map(|self_ptr| {
-            let (self_expr, explicit_self) = ty::get_explicit_self(cx, trait_.span, self_ptr);
-
-            self_args.push(self_expr);
-            nonstatic = true;
-
-            explicit_self
-        });
-
-        for (ty, name) in self.args.iter() {
-            let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
-            let ident = cx.ident_of(name, trait_.span);
-            arg_tys.push((ident, ast_ty));
-
-            let arg_expr = cx.expr_ident(trait_.span, ident);
-
-            match *ty {
-                // for static methods, just treat any Self
-                // arguments as a normal arg
-                Self_ if nonstatic => {
-                    self_args.push(arg_expr);
-                }
-                Ptr(ref ty, _) if (if let Self_ = **ty { true } else { false }) && nonstatic => {
-                    self_args.push(cx.expr_deref(trait_.span, arg_expr))
-                }
-                _ => {
-                    nonself_args.push(arg_expr);
-                }
-            }
-        }
-
-        (ast_explicit_self, self_args, nonself_args, arg_tys)
-    }
-
-    fn create_method(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'_>,
-        type_ident: Ident,
-        generics: &Generics,
-        explicit_self: Option<ast::ExplicitSelf>,
-        arg_types: Vec<(Ident, P<ast::Ty>)>,
-        body: P<Expr>,
-    ) -> ast::AssocItem {
-        // Create the generics that aren't for `Self`.
-        let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
-
-        let args = {
-            let self_args = explicit_self.map(|explicit_self| {
-                let ident = Ident::with_dummy_span(kw::SelfLower).with_span_pos(trait_.span);
-                ast::Param::from_self(ast::AttrVec::default(), explicit_self, ident)
-            });
-            let nonself_args =
-                arg_types.into_iter().map(|(name, ty)| cx.param(trait_.span, name, ty));
-            self_args.into_iter().chain(nonself_args).collect()
-        };
-
-        let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident);
-
-        let method_ident = cx.ident_of(self.name, trait_.span);
-        let fn_decl = cx.fn_decl(args, ast::FunctionRetTy::Ty(ret_type));
-        let body_block = cx.block_expr(body);
-
-        let unsafety = if self.is_unsafe { ast::Unsafety::Unsafe } else { ast::Unsafety::Normal };
-
-        let trait_lo_sp = trait_.span.shrink_to_lo();
-
-        let sig = ast::FnSig {
-            header: ast::FnHeader { unsafety, ext: ast::Extern::None, ..ast::FnHeader::default() },
-            decl: fn_decl,
-        };
-
-        // Create the method.
-        ast::AssocItem {
-            id: ast::DUMMY_NODE_ID,
-            attrs: self.attributes.clone(),
-            generics: fn_generics,
-            span: trait_.span,
-            vis: respan(trait_lo_sp, ast::VisibilityKind::Inherited),
-            defaultness: ast::Defaultness::Final,
-            ident: method_ident,
-            kind: ast::AssocItemKind::Fn(sig, Some(body_block)),
-            tokens: None,
-        }
-    }
-
-    /// ```
-    /// #[derive(PartialEq)]
-    /// # struct Dummy;
-    /// struct A { x: i32, y: i32 }
-    ///
-    /// // equivalent to:
-    /// impl PartialEq for A {
-    ///     fn eq(&self, other: &A) -> bool {
-    ///         match *self {
-    ///             A {x: ref __self_0_0, y: ref __self_0_1} => {
-    ///                 match *other {
-    ///                     A {x: ref __self_1_0, y: ref __self_1_1} => {
-    ///                         __self_0_0.eq(__self_1_0) && __self_0_1.eq(__self_1_1)
-    ///                     }
-    ///                 }
-    ///             }
-    ///         }
-    ///     }
-    /// }
-    ///
-    /// // or if A is repr(packed) - note fields are matched by-value
-    /// // instead of by-reference.
-    /// impl PartialEq for A {
-    ///     fn eq(&self, other: &A) -> bool {
-    ///         match *self {
-    ///             A {x: __self_0_0, y: __self_0_1} => {
-    ///                 match other {
-    ///                     A {x: __self_1_0, y: __self_1_1} => {
-    ///                         __self_0_0.eq(&__self_1_0) && __self_0_1.eq(&__self_1_1)
-    ///                     }
-    ///                 }
-    ///             }
-    ///         }
-    ///     }
-    /// }
-    /// ```
-    fn expand_struct_method_body<'b>(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'b>,
-        struct_def: &'b VariantData,
-        type_ident: Ident,
-        self_args: &[P<Expr>],
-        nonself_args: &[P<Expr>],
-        use_temporaries: bool,
-    ) -> P<Expr> {
-        let mut raw_fields = Vec::new(); // Vec<[fields of self],
-        // [fields of next Self arg], [etc]>
-        let mut patterns = Vec::new();
-        for i in 0..self_args.len() {
-            let struct_path = cx.path(trait_.span, vec![type_ident]);
-            let (pat, ident_expr) = trait_.create_struct_pattern(
-                cx,
-                struct_path,
-                struct_def,
-                &format!("__self_{}", i),
-                ast::Mutability::Not,
-                use_temporaries,
-            );
-            patterns.push(pat);
-            raw_fields.push(ident_expr);
-        }
-
-        // transpose raw_fields
-        let fields = if !raw_fields.is_empty() {
-            let mut raw_fields = raw_fields.into_iter().map(|v| v.into_iter());
-            let first_field = raw_fields.next().unwrap();
-            let mut other_fields: Vec<vec::IntoIter<_>> = raw_fields.collect();
-            first_field
-                .map(|(span, opt_id, field, attrs)| FieldInfo {
-                    span,
-                    name: opt_id,
-                    self_: field,
-                    other: other_fields
-                        .iter_mut()
-                        .map(|l| match l.next().unwrap() {
-                            (.., ex, _) => ex,
-                        })
-                        .collect(),
-                    attrs,
-                })
-                .collect()
-        } else {
-            cx.span_bug(trait_.span, "no `self` parameter for method in generic `derive`")
-        };
-
-        // body of the inner most destructuring match
-        let mut body = self.call_substructure_method(
-            cx,
-            trait_,
-            type_ident,
-            self_args,
-            nonself_args,
-            &Struct(struct_def, fields),
-        );
-
-        // make a series of nested matches, to destructure the
-        // structs. This is actually right-to-left, but it shouldn't
-        // matter.
-        for (arg_expr, pat) in self_args.iter().zip(patterns) {
-            body = cx.expr_match(
-                trait_.span,
-                arg_expr.clone(),
-                vec![cx.arm(trait_.span, pat.clone(), body)],
-            )
-        }
-
-        body
-    }
-
-    fn expand_static_struct_method_body(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'_>,
-        struct_def: &VariantData,
-        type_ident: Ident,
-        self_args: &[P<Expr>],
-        nonself_args: &[P<Expr>],
-    ) -> P<Expr> {
-        let summary = trait_.summarise_struct(cx, struct_def);
-
-        self.call_substructure_method(
-            cx,
-            trait_,
-            type_ident,
-            self_args,
-            nonself_args,
-            &StaticStruct(struct_def, summary),
-        )
-    }
-
-    /// ```
-    /// #[derive(PartialEq)]
-    /// # struct Dummy;
-    /// enum A {
-    ///     A1,
-    ///     A2(i32)
-    /// }
-    ///
-    /// // is equivalent to
-    ///
-    /// impl PartialEq for A {
-    ///     fn eq(&self, other: &A) -> ::bool {
-    ///         match (&*self, &*other) {
-    ///             (&A1, &A1) => true,
-    ///             (&A2(ref self_0),
-    ///              &A2(ref __arg_1_0)) => (*self_0).eq(&(*__arg_1_0)),
-    ///             _ => {
-    ///                 let __self_vi = match *self { A1(..) => 0, A2(..) => 1 };
-    ///                 let __arg_1_vi = match *other { A1(..) => 0, A2(..) => 1 };
-    ///                 false
-    ///             }
-    ///         }
-    ///     }
-    /// }
-    /// ```
-    ///
-    /// (Of course `__self_vi` and `__arg_1_vi` are unused for
-    /// `PartialEq`, and those subcomputations will hopefully be removed
-    /// as their results are unused. The point of `__self_vi` and
-    /// `__arg_1_vi` is for `PartialOrd`; see #15503.)
-    fn expand_enum_method_body<'b>(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'b>,
-        enum_def: &'b EnumDef,
-        type_attrs: &[ast::Attribute],
-        type_ident: Ident,
-        self_args: Vec<P<Expr>>,
-        nonself_args: &[P<Expr>],
-    ) -> P<Expr> {
-        self.build_enum_match_tuple(
-            cx,
-            trait_,
-            enum_def,
-            type_attrs,
-            type_ident,
-            self_args,
-            nonself_args,
-        )
-    }
-
-    /// Creates a match for a tuple of all `self_args`, where either all
-    /// variants match, or it falls into a catch-all for when one variant
-    /// does not match.
-
-    /// There are N + 1 cases because is a case for each of the N
-    /// variants where all of the variants match, and one catch-all for
-    /// when one does not match.
-
-    /// As an optimization we generate code which checks whether all variants
-    /// match first which makes llvm see that C-like enums can be compiled into
-    /// a simple equality check (for PartialEq).
-
-    /// The catch-all handler is provided access the variant index values
-    /// for each of the self-args, carried in precomputed variables.
-
-    /// ```{.text}
-    /// let __self0_vi = unsafe {
-    ///     std::intrinsics::discriminant_value(&self) } as i32;
-    /// let __self1_vi = unsafe {
-    ///     std::intrinsics::discriminant_value(&arg1) } as i32;
-    /// let __self2_vi = unsafe {
-    ///     std::intrinsics::discriminant_value(&arg2) } as i32;
-    ///
-    /// if __self0_vi == __self1_vi && __self0_vi == __self2_vi && ... {
-    ///     match (...) {
-    ///         (Variant1, Variant1, ...) => Body1
-    ///         (Variant2, Variant2, ...) => Body2,
-    ///         ...
-    ///         _ => ::core::intrinsics::unreachable()
-    ///     }
-    /// }
-    /// else {
-    ///     ... // catch-all remainder can inspect above variant index values.
-    /// }
-    /// ```
-    fn build_enum_match_tuple<'b>(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'b>,
-        enum_def: &'b EnumDef,
-        type_attrs: &[ast::Attribute],
-        type_ident: Ident,
-        mut self_args: Vec<P<Expr>>,
-        nonself_args: &[P<Expr>],
-    ) -> P<Expr> {
-        let sp = trait_.span;
-        let variants = &enum_def.variants;
-
-        let self_arg_names = iter::once("__self".to_string())
-            .chain(
-                self_args
-                    .iter()
-                    .enumerate()
-                    .skip(1)
-                    .map(|(arg_count, _self_arg)| format!("__arg_{}", arg_count)),
-            )
-            .collect::<Vec<String>>();
-
-        let self_arg_idents =
-            self_arg_names.iter().map(|name| cx.ident_of(name, sp)).collect::<Vec<ast::Ident>>();
-
-        // The `vi_idents` will be bound, solely in the catch-all, to
-        // a series of let statements mapping each self_arg to an int
-        // value corresponding to its discriminant.
-        let vi_idents = self_arg_names
-            .iter()
-            .map(|name| {
-                let vi_suffix = format!("{}_vi", &name[..]);
-                cx.ident_of(&vi_suffix[..], trait_.span)
-            })
-            .collect::<Vec<ast::Ident>>();
-
-        // Builds, via callback to call_substructure_method, the
-        // delegated expression that handles the catch-all case,
-        // using `__variants_tuple` to drive logic if necessary.
-        let catch_all_substructure =
-            EnumNonMatchingCollapsed(self_arg_idents, &variants[..], &vi_idents[..]);
-
-        let first_fieldless = variants.iter().find(|v| v.data.fields().is_empty());
-
-        // These arms are of the form:
-        // (Variant1, Variant1, ...) => Body1
-        // (Variant2, Variant2, ...) => Body2
-        // ...
-        // where each tuple has length = self_args.len()
-        let mut match_arms: Vec<ast::Arm> = variants
-            .iter()
-            .enumerate()
-            .filter(|&(_, v)| !(self.unify_fieldless_variants && v.data.fields().is_empty()))
-            .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::Mutability::Not,
-                    );
-                    (cx.pat(sp, PatKind::Ref(p, ast::Mutability::Not)), idents)
-                };
-
-                // A single arm has form (&VariantK, &VariantK, ...) => BodyK
-                // (see "Final wrinkle" note below for why.)
-                let mut subpats = Vec::with_capacity(self_arg_names.len());
-                let mut self_pats_idents = Vec::with_capacity(self_arg_names.len() - 1);
-                let first_self_pat_idents = {
-                    let (p, idents) = mk_self_pat(cx, &self_arg_names[0]);
-                    subpats.push(p);
-                    idents
-                };
-                for self_arg_name in &self_arg_names[1..] {
-                    let (p, idents) = mk_self_pat(cx, &self_arg_name[..]);
-                    subpats.push(p);
-                    self_pats_idents.push(idents);
-                }
-
-                // Here is the pat = `(&VariantK, &VariantK, ...)`
-                let single_pat = cx.pat_tuple(sp, subpats);
-
-                // For the BodyK, we need to delegate to our caller,
-                // passing it an EnumMatching to indicate which case
-                // we are in.
-
-                // All of the Self args have the same variant in these
-                // cases.  So we transpose the info in self_pats_idents
-                // to gather the getter expressions together, in the
-                // form that EnumMatching expects.
-
-                // The transposition is driven by walking across the
-                // arg fields of the variant for the first self pat.
-                let field_tuples = first_self_pat_idents
-                    .into_iter()
-                    .enumerate()
-                    // For each arg field of self, pull out its getter expr ...
-                    .map(|(field_index, (sp, opt_ident, self_getter_expr, attrs))| {
-                        // ... but FieldInfo also wants getter expr
-                        // for matching other arguments of Self type;
-                        // so walk across the *other* self_pats_idents
-                        // and pull out getter for same field in each
-                        // of them (using `field_index` tracked above).
-                        // That is the heart of the transposition.
-                        let others = self_pats_idents
-                            .iter()
-                            .map(|fields| {
-                                let (_, _opt_ident, ref other_getter_expr, _) = fields[field_index];
-
-                                // All Self args have same variant, so
-                                // opt_idents are the same.  (Assert
-                                // here to make it self-evident that
-                                // it is okay to ignore `_opt_ident`.)
-                                assert!(opt_ident == _opt_ident);
-
-                                other_getter_expr.clone()
-                            })
-                            .collect::<Vec<P<Expr>>>();
-
-                        FieldInfo {
-                            span: sp,
-                            name: opt_ident,
-                            self_: self_getter_expr,
-                            other: others,
-                            attrs,
-                        }
-                    })
-                    .collect::<Vec<FieldInfo<'_>>>();
-
-                // Now, for some given VariantK, we have built up
-                // expressions for referencing every field of every
-                // Self arg, assuming all are instances of VariantK.
-                // Build up code associated with such a case.
-                let substructure = EnumMatching(index, variants.len(), variant, field_tuples);
-                let arm_expr = self.call_substructure_method(
-                    cx,
-                    trait_,
-                    type_ident,
-                    &self_args[..],
-                    nonself_args,
-                    &substructure,
-                );
-
-                cx.arm(sp, single_pat, arm_expr)
-            })
-            .collect();
-
-        let default = match first_fieldless {
-            Some(v) if self.unify_fieldless_variants => {
-                // We need a default case that handles the fieldless variants.
-                // The index and actual variant aren't meaningful in this case,
-                // so just use whatever
-                let substructure = EnumMatching(0, variants.len(), v, Vec::new());
-                Some(self.call_substructure_method(
-                    cx,
-                    trait_,
-                    type_ident,
-                    &self_args[..],
-                    nonself_args,
-                    &substructure,
-                ))
-            }
-            _ if variants.len() > 1 && self_args.len() > 1 => {
-                // Since we know that all the arguments will match if we reach
-                // the match expression we add the unreachable intrinsics as the
-                // result of the catch all which should help llvm in optimizing it
-                Some(deriving::call_intrinsic(cx, sp, "unreachable", vec![]))
-            }
-            _ => None,
-        };
-        if let Some(arm) = default {
-            match_arms.push(cx.arm(sp, cx.pat_wild(sp), arm));
-        }
-
-        // We will usually need the catch-all after matching the
-        // tuples `(VariantK, VariantK, ...)` for each VariantK of the
-        // enum.  But:
-        //
-        // * when there is only one Self arg, the arms above suffice
-        // (and the deriving we call back into may not be prepared to
-        // handle EnumNonMatchCollapsed), and,
-        //
-        // * when the enum has only one variant, the single arm that
-        // is already present always suffices.
-        //
-        // * In either of the two cases above, if we *did* add a
-        //   catch-all `_` match, it would trigger the
-        //   unreachable-pattern error.
-        //
-        if variants.len() > 1 && self_args.len() > 1 {
-            // Build a series of let statements mapping each self_arg
-            // to its discriminant value. If this is a C-style enum
-            // with a specific repr type, then casts the values to
-            // that type.  Otherwise casts to `i32` (the default repr
-            // type).
-            //
-            // i.e., for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
-            // with three Self args, builds three statements:
-            //
-            // ```
-            // let __self0_vi = unsafe {
-            //     std::intrinsics::discriminant_value(&self) } as i32;
-            // let __self1_vi = unsafe {
-            //     std::intrinsics::discriminant_value(&arg1) } as i32;
-            // let __self2_vi = unsafe {
-            //     std::intrinsics::discriminant_value(&arg2) } as i32;
-            // ```
-            let mut index_let_stmts: Vec<ast::Stmt> = Vec::with_capacity(vi_idents.len() + 1);
-
-            // We also build an expression which checks whether all discriminants are equal
-            // discriminant_test = __self0_vi == __self1_vi && __self0_vi == __self2_vi && ...
-            let mut discriminant_test = cx.expr_bool(sp, true);
-
-            let target_type_name = find_repr_type_name(&cx.parse_sess, type_attrs);
-
-            let mut first_ident = None;
-            for (&ident, self_arg) in vi_idents.iter().zip(&self_args) {
-                let self_addr = cx.expr_addr_of(sp, self_arg.clone());
-                let variant_value =
-                    deriving::call_intrinsic(cx, sp, "discriminant_value", vec![self_addr]);
-
-                let target_ty = cx.ty_ident(sp, cx.ident_of(target_type_name, sp));
-                let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
-                let let_stmt = cx.stmt_let(sp, false, ident, variant_disr);
-                index_let_stmts.push(let_stmt);
-
-                match first_ident {
-                    Some(first) => {
-                        let first_expr = cx.expr_ident(sp, first);
-                        let id = cx.expr_ident(sp, ident);
-                        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);
-                    }
-                }
-            }
-
-            let arm_expr = self.call_substructure_method(
-                cx,
-                trait_,
-                type_ident,
-                &self_args[..],
-                nonself_args,
-                &catch_all_substructure,
-            );
-
-            // Final wrinkle: the self_args are expressions that deref
-            // down to desired places, but we cannot actually deref
-            // them when they are fed as r-values into a tuple
-            // expression; here add a layer of borrowing, turning
-            // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
-            self_args.map_in_place(|self_arg| cx.expr_addr_of(sp, self_arg));
-            let match_arg = cx.expr(sp, ast::ExprKind::Tup(self_args));
-
-            // Lastly we create an expression which branches on all discriminants being equal
-            //  if discriminant_test {
-            //      match (...) {
-            //          (Variant1, Variant1, ...) => Body1
-            //          (Variant2, Variant2, ...) => Body2,
-            //          ...
-            //          _ => ::core::intrinsics::unreachable()
-            //      }
-            //  }
-            //  else {
-            //      <delegated expression referring to __self0_vi, et al.>
-            //  }
-            let all_match = cx.expr_match(sp, match_arg, match_arms);
-            let arm_expr = cx.expr_if(sp, discriminant_test, all_match, Some(arm_expr));
-            index_let_stmts.push(cx.stmt_expr(arm_expr));
-            cx.expr_block(cx.block(sp, index_let_stmts))
-        } else if variants.is_empty() {
-            // As an additional wrinkle, For a zero-variant enum A,
-            // currently the compiler
-            // will accept `fn (a: &Self) { match   *a   { } }`
-            // but rejects `fn (a: &Self) { match (&*a,) { } }`
-            // as well as  `fn (a: &Self) { match ( *a,) { } }`
-            //
-            // This means that the strategy of building up a tuple of
-            // all Self arguments fails when Self is a zero variant
-            // enum: rustc rejects the expanded program, even though
-            // the actual code tends to be impossible to execute (at
-            // least safely), according to the type system.
-            //
-            // The most expedient fix for this is to just let the
-            // code fall through to the catch-all.  But even this is
-            // error-prone, since the catch-all as defined above would
-            // generate code like this:
-            //
-            //     _ => { let __self0 = match *self { };
-            //            let __self1 = match *__arg_0 { };
-            //            <catch-all-expr> }
-            //
-            // Which is yields bindings for variables which type
-            // inference cannot resolve to unique types.
-            //
-            // One option to the above might be to add explicit type
-            // annotations.  But the *only* reason to go down that path
-            // would be to try to make the expanded output consistent
-            // with the case when the number of enum variants >= 1.
-            //
-            // That just isn't worth it.  In fact, trying to generate
-            // sensible code for *any* deriving on a zero-variant enum
-            // does not make sense.  But at the same time, for now, we
-            // do not want to cause a compile failure just because the
-            // user happened to attach a deriving to their
-            // zero-variant enum.
-            //
-            // Instead, just generate a failing expression for the
-            // zero variant case, skipping matches and also skipping
-            // delegating back to the end user code entirely.
-            //
-            // (See also #4499 and #12609; note that some of the
-            // discussions there influence what choice we make here;
-            // e.g., if we feature-gate `match x { ... }` when x refers
-            // to an uninhabited type (e.g., a zero-variant enum or a
-            // type holding such an enum), but do not feature-gate
-            // zero-variant enums themselves, then attempting to
-            // derive Debug on such a type could here generate code
-            // that needs the feature gate enabled.)
-
-            deriving::call_intrinsic(cx, sp, "unreachable", vec![])
-        } else {
-            // Final wrinkle: the self_args are expressions that deref
-            // down to desired places, but we cannot actually deref
-            // them when they are fed as r-values into a tuple
-            // expression; here add a layer of borrowing, turning
-            // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
-            self_args.map_in_place(|self_arg| cx.expr_addr_of(sp, self_arg));
-            let match_arg = cx.expr(sp, ast::ExprKind::Tup(self_args));
-            cx.expr_match(sp, match_arg, match_arms)
-        }
-    }
-
-    fn expand_static_enum_method_body(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        trait_: &TraitDef<'_>,
-        enum_def: &EnumDef,
-        type_ident: Ident,
-        self_args: &[P<Expr>],
-        nonself_args: &[P<Expr>],
-    ) -> P<Expr> {
-        let summary = enum_def
-            .variants
-            .iter()
-            .map(|v| {
-                let sp = v.span.with_ctxt(trait_.span.ctxt());
-                let summary = trait_.summarise_struct(cx, &v.data);
-                (v.ident, sp, summary)
-            })
-            .collect();
-        self.call_substructure_method(
-            cx,
-            trait_,
-            type_ident,
-            self_args,
-            nonself_args,
-            &StaticEnum(enum_def, summary),
-        )
-    }
-}
-
-// general helper methods.
-impl<'a> TraitDef<'a> {
-    fn summarise_struct(&self, cx: &mut ExtCtxt<'_>, struct_def: &VariantData) -> StaticFields {
-        let mut named_idents = Vec::new();
-        let mut just_spans = Vec::new();
-        for field in struct_def.fields() {
-            let sp = field.span.with_ctxt(self.span.ctxt());
-            match field.ident {
-                Some(ident) => named_idents.push((ident, sp)),
-                _ => just_spans.push(sp),
-            }
-        }
-
-        let is_tuple = if let ast::VariantData::Tuple(..) = struct_def { true } else { false };
-        match (just_spans.is_empty(), named_idents.is_empty()) {
-            (false, false) => cx.span_bug(
-                self.span,
-                "a struct with named and unnamed \
-                                          fields in generic `derive`",
-            ),
-            // named fields
-            (_, false) => Named(named_idents),
-            // unnamed fields
-            (false, _) => Unnamed(just_spans, is_tuple),
-            // empty
-            _ => Named(Vec::new()),
-        }
-    }
-
-    fn create_subpatterns(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        field_paths: Vec<ast::Ident>,
-        mutbl: ast::Mutability,
-        use_temporaries: bool,
-    ) -> Vec<P<ast::Pat>> {
-        field_paths
-            .iter()
-            .map(|path| {
-                let binding_mode = if use_temporaries {
-                    ast::BindingMode::ByValue(ast::Mutability::Not)
-                } else {
-                    ast::BindingMode::ByRef(mutbl)
-                };
-                cx.pat(path.span, PatKind::Ident(binding_mode, (*path).clone(), None))
-            })
-            .collect()
-    }
-
-    fn create_struct_pattern(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        struct_path: ast::Path,
-        struct_def: &'a VariantData,
-        prefix: &str,
-        mutbl: ast::Mutability,
-        use_temporaries: bool,
-    ) -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
-        let mut paths = Vec::new();
-        let mut ident_exprs = Vec::new();
-        for (i, struct_field) in struct_def.fields().iter().enumerate() {
-            let sp = struct_field.span.with_ctxt(self.span.ctxt());
-            let ident = cx.ident_of(&format!("{}_{}", prefix, i), self.span);
-            paths.push(ident.with_span_pos(sp));
-            let val = cx.expr_path(cx.path_ident(sp, ident));
-            let val = if use_temporaries { val } else { cx.expr_deref(sp, val) };
-            let val = cx.expr(sp, ast::ExprKind::Paren(val));
-
-            ident_exprs.push((sp, struct_field.ident, val, &struct_field.attrs[..]));
-        }
-
-        let subpats = self.create_subpatterns(cx, paths, mutbl, use_temporaries);
-        let pattern = match *struct_def {
-            VariantData::Struct(..) => {
-                let field_pats = subpats
-                    .into_iter()
-                    .zip(&ident_exprs)
-                    .map(|(pat, &(sp, ident, ..))| {
-                        if ident.is_none() {
-                            cx.span_bug(sp, "a braced struct with unnamed fields in `derive`");
-                        }
-                        ast::FieldPat {
-                            ident: ident.unwrap(),
-                            is_shorthand: false,
-                            attrs: ast::AttrVec::new(),
-                            id: ast::DUMMY_NODE_ID,
-                            span: pat.span.with_ctxt(self.span.ctxt()),
-                            pat,
-                            is_placeholder: false,
-                        }
-                    })
-                    .collect();
-                cx.pat_struct(self.span, struct_path, field_pats)
-            }
-            VariantData::Tuple(..) => cx.pat_tuple_struct(self.span, struct_path, subpats),
-            VariantData::Unit(..) => cx.pat_path(self.span, struct_path),
-        };
-
-        (pattern, ident_exprs)
-    }
-
-    fn create_enum_variant_pattern(
-        &self,
-        cx: &mut ExtCtxt<'_>,
-        enum_ident: ast::Ident,
-        variant: &'a ast::Variant,
-        prefix: &str,
-        mutbl: ast::Mutability,
-    ) -> (P<ast::Pat>, Vec<(Span, Option<Ident>, P<Expr>, &'a [ast::Attribute])>) {
-        let sp = variant.span.with_ctxt(self.span.ctxt());
-        let variant_path = cx.path(sp, vec![enum_ident, variant.ident]);
-        let use_temporaries = false; // enums can't be repr(packed)
-        self.create_struct_pattern(cx, variant_path, &variant.data, prefix, mutbl, use_temporaries)
-    }
-}
-
-// helpful premade recipes
-
-pub fn cs_fold_fields<'a, F>(
-    use_foldl: bool,
-    mut f: F,
-    base: P<Expr>,
-    cx: &mut ExtCtxt<'_>,
-    all_fields: &[FieldInfo<'a>],
-) -> P<Expr>
-where
-    F: FnMut(&mut ExtCtxt<'_>, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
-{
-    if use_foldl {
-        all_fields
-            .iter()
-            .fold(base, |old, field| f(cx, field.span, old, field.self_.clone(), &field.other))
-    } else {
-        all_fields
-            .iter()
-            .rev()
-            .fold(base, |old, field| f(cx, field.span, old, field.self_.clone(), &field.other))
-    }
-}
-
-pub fn cs_fold_enumnonmatch(
-    mut enum_nonmatch_f: EnumNonMatchCollapsedFunc<'_>,
-    cx: &mut ExtCtxt<'_>,
-    trait_span: Span,
-    substructure: &Substructure<'_>,
-) -> P<Expr> {
-    match *substructure.fields {
-        EnumNonMatchingCollapsed(ref all_args, _, tuple) => {
-            enum_nonmatch_f(cx, trait_span, (&all_args[..], tuple), substructure.nonself_args)
-        }
-        _ => cx.span_bug(trait_span, "cs_fold_enumnonmatch expected an EnumNonMatchingCollapsed"),
-    }
-}
-
-pub fn cs_fold_static(cx: &mut ExtCtxt<'_>, trait_span: Span) -> P<Expr> {
-    cx.span_bug(trait_span, "static function in `derive`")
-}
-
-/// Fold the fields. `use_foldl` controls whether this is done
-/// left-to-right (`true`) or right-to-left (`false`).
-pub fn cs_fold<F>(
-    use_foldl: bool,
-    f: F,
-    base: P<Expr>,
-    enum_nonmatch_f: EnumNonMatchCollapsedFunc<'_>,
-    cx: &mut ExtCtxt<'_>,
-    trait_span: Span,
-    substructure: &Substructure<'_>,
-) -> P<Expr>
-where
-    F: FnMut(&mut ExtCtxt<'_>, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
-{
-    match *substructure.fields {
-        EnumMatching(.., ref all_fields) | Struct(_, ref all_fields) => {
-            cs_fold_fields(use_foldl, f, base, cx, all_fields)
-        }
-        EnumNonMatchingCollapsed(..) => {
-            cs_fold_enumnonmatch(enum_nonmatch_f, cx, trait_span, substructure)
-        }
-        StaticEnum(..) | StaticStruct(..) => cs_fold_static(cx, trait_span),
-    }
-}
-
-/// Function to fold over fields, with three cases, to generate more efficient and concise code.
-/// When the `substructure` has grouped fields, there are two cases:
-/// Zero fields: call the base case function with `None` (like the usual base case of `cs_fold`).
-/// One or more fields: call the base case function on the first value (which depends on
-/// `use_fold`), and use that as the base case. Then perform `cs_fold` on the remainder of the
-/// fields.
-/// When the `substructure` is a `EnumNonMatchingCollapsed`, the result of `enum_nonmatch_f`
-/// is returned. Statics may not be folded over.
-/// See `cs_op` in `partial_ord.rs` for a model example.
-pub fn cs_fold1<F, B>(
-    use_foldl: bool,
-    f: F,
-    mut b: B,
-    enum_nonmatch_f: EnumNonMatchCollapsedFunc<'_>,
-    cx: &mut ExtCtxt<'_>,
-    trait_span: Span,
-    substructure: &Substructure<'_>,
-) -> P<Expr>
-where
-    F: FnMut(&mut ExtCtxt<'_>, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
-    B: FnMut(&mut ExtCtxt<'_>, Option<(Span, P<Expr>, &[P<Expr>])>) -> P<Expr>,
-{
-    match *substructure.fields {
-        EnumMatching(.., ref all_fields) | Struct(_, ref all_fields) => {
-            let (base, all_fields) = match (all_fields.is_empty(), use_foldl) {
-                (false, true) => {
-                    let field = &all_fields[0];
-                    let args = (field.span, field.self_.clone(), &field.other[..]);
-                    (b(cx, Some(args)), &all_fields[1..])
-                }
-                (false, false) => {
-                    let idx = all_fields.len() - 1;
-                    let field = &all_fields[idx];
-                    let args = (field.span, field.self_.clone(), &field.other[..]);
-                    (b(cx, Some(args)), &all_fields[..idx])
-                }
-                (true, _) => (b(cx, None), &all_fields[..]),
-            };
-
-            cs_fold_fields(use_foldl, f, base, cx, all_fields)
-        }
-        EnumNonMatchingCollapsed(..) => {
-            cs_fold_enumnonmatch(enum_nonmatch_f, cx, trait_span, substructure)
-        }
-        StaticEnum(..) | StaticStruct(..) => cs_fold_static(cx, trait_span),
-    }
-}
-
-/// Returns `true` if the type has no value fields
-/// (for an enum, no variant has any fields)
-pub fn is_type_without_fields(item: &Annotatable) -> bool {
-    if let Annotatable::Item(ref item) = *item {
-        match item.kind {
-            ast::ItemKind::Enum(ref enum_def, _) => {
-                enum_def.variants.iter().all(|v| v.data.fields().is_empty())
-            }
-            ast::ItemKind::Struct(ref variant_data, _) => variant_data.fields().is_empty(),
-            _ => false,
-        }
-    } else {
-        false
-    }
-}
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
deleted file mode 100644
index 7eab15aff77..00000000000
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-//! A mini version of ast::Ty, which is easier to use, and features an explicit `Self` type to use
-//! when specifying impls to be derived.
-
-pub use PtrTy::*;
-pub use Ty::*;
-
-use syntax::ast::{self, Expr, GenericArg, GenericParamKind, Generics, Ident, SelfKind};
-use syntax::ptr::P;
-use syntax::source_map::{respan, DUMMY_SP};
-use syntax_expand::base::ExtCtxt;
-use syntax_pos::symbol::kw;
-use syntax_pos::Span;
-
-/// The types of pointers
-#[derive(Clone)]
-pub enum PtrTy {
-    /// &'lifetime mut
-    Borrowed(Option<Ident>, ast::Mutability),
-    /// *mut
-    #[allow(dead_code)]
-    Raw(ast::Mutability),
-}
-
-/// A path, e.g., `::std::option::Option::<i32>` (global). Has support
-/// for type parameters and a lifetime.
-#[derive(Clone)]
-pub struct Path<'a> {
-    path: Vec<&'a str>,
-    lifetime: Option<Ident>,
-    params: Vec<Box<Ty<'a>>>,
-    kind: PathKind,
-}
-
-#[derive(Clone)]
-pub enum PathKind {
-    Local,
-    Global,
-    Std,
-}
-
-impl<'a> Path<'a> {
-    pub fn new(path: Vec<&str>) -> Path<'_> {
-        Path::new_(path, None, Vec::new(), PathKind::Std)
-    }
-    pub fn new_local(path: &str) -> Path<'_> {
-        Path::new_(vec![path], None, Vec::new(), PathKind::Local)
-    }
-    pub fn new_<'r>(
-        path: Vec<&'r str>,
-        lifetime: Option<Ident>,
-        params: Vec<Box<Ty<'r>>>,
-        kind: PathKind,
-    ) -> Path<'r> {
-        Path { path, lifetime, params, kind }
-    }
-
-    pub fn to_ty(
-        &self,
-        cx: &ExtCtxt<'_>,
-        span: Span,
-        self_ty: Ident,
-        self_generics: &Generics,
-    ) -> P<ast::Ty> {
-        cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
-    }
-    pub fn to_path(
-        &self,
-        cx: &ExtCtxt<'_>,
-        span: Span,
-        self_ty: Ident,
-        self_generics: &Generics,
-    ) -> ast::Path {
-        let mut idents = self.path.iter().map(|s| cx.ident_of(*s, span)).collect();
-        let lt = mk_lifetimes(cx, span, &self.lifetime);
-        let tys: Vec<P<ast::Ty>> =
-            self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
-        let params = lt
-            .into_iter()
-            .map(|lt| GenericArg::Lifetime(lt))
-            .chain(tys.into_iter().map(|ty| GenericArg::Type(ty)))
-            .collect();
-
-        match self.kind {
-            PathKind::Global => cx.path_all(span, true, idents, params),
-            PathKind::Local => cx.path_all(span, false, idents, params),
-            PathKind::Std => {
-                let def_site = cx.with_def_site_ctxt(DUMMY_SP);
-                idents.insert(0, Ident::new(kw::DollarCrate, def_site));
-                cx.path_all(span, false, idents, params)
-            }
-        }
-    }
-}
-
-/// A type. Supports pointers, Self, and literals.
-#[derive(Clone)]
-pub enum Ty<'a> {
-    Self_,
-    /// &/Box/ Ty
-    Ptr(Box<Ty<'a>>, PtrTy),
-    /// mod::mod::Type<[lifetime], [Params...]>, including a plain type
-    /// parameter, and things like `i32`
-    Literal(Path<'a>),
-    /// includes unit
-    Tuple(Vec<Ty<'a>>),
-}
-
-pub fn borrowed_ptrty() -> PtrTy {
-    Borrowed(None, ast::Mutability::Not)
-}
-pub fn borrowed(ty: Box<Ty<'_>>) -> Ty<'_> {
-    Ptr(ty, borrowed_ptrty())
-}
-
-pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
-    Some(Some(borrowed_ptrty()))
-}
-
-pub fn borrowed_self<'r>() -> Ty<'r> {
-    borrowed(Box::new(Self_))
-}
-
-pub fn nil_ty<'r>() -> Ty<'r> {
-    Tuple(Vec::new())
-}
-
-fn mk_lifetime(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Option<ast::Lifetime> {
-    lt.map(|ident| cx.lifetime(span, ident))
-}
-
-fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Vec<ast::Lifetime> {
-    mk_lifetime(cx, span, lt).into_iter().collect()
-}
-
-impl<'a> Ty<'a> {
-    pub fn to_ty(
-        &self,
-        cx: &ExtCtxt<'_>,
-        span: Span,
-        self_ty: Ident,
-        self_generics: &Generics,
-    ) -> P<ast::Ty> {
-        match *self {
-            Ptr(ref ty, ref ptr) => {
-                let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
-                match *ptr {
-                    Borrowed(ref lt, mutbl) => {
-                        let lt = mk_lifetime(cx, span, lt);
-                        cx.ty_rptr(span, raw_ty, lt, mutbl)
-                    }
-                    Raw(mutbl) => cx.ty_ptr(span, raw_ty, mutbl),
-                }
-            }
-            Literal(ref p) => p.to_ty(cx, span, self_ty, self_generics),
-            Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
-            Tuple(ref fields) => {
-                let ty = ast::TyKind::Tup(
-                    fields.iter().map(|f| f.to_ty(cx, span, self_ty, self_generics)).collect(),
-                );
-                cx.ty(span, ty)
-            }
-        }
-    }
-
-    pub fn to_path(
-        &self,
-        cx: &ExtCtxt<'_>,
-        span: Span,
-        self_ty: Ident,
-        generics: &Generics,
-    ) -> ast::Path {
-        match *self {
-            Self_ => {
-                let params: Vec<_> = generics
-                    .params
-                    .iter()
-                    .map(|param| match param.kind {
-                        GenericParamKind::Lifetime { .. } => {
-                            GenericArg::Lifetime(ast::Lifetime { id: param.id, ident: param.ident })
-                        }
-                        GenericParamKind::Type { .. } => {
-                            GenericArg::Type(cx.ty_ident(span, param.ident))
-                        }
-                        GenericParamKind::Const { .. } => {
-                            GenericArg::Const(cx.const_ident(span, param.ident))
-                        }
-                    })
-                    .collect();
-
-                cx.path_all(span, false, vec![self_ty], params)
-            }
-            Literal(ref p) => p.to_path(cx, span, self_ty, generics),
-            Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"),
-            Tuple(..) => cx.span_bug(span, "tuple in a path in generic `derive`"),
-        }
-    }
-}
-
-fn mk_ty_param(
-    cx: &ExtCtxt<'_>,
-    span: Span,
-    name: &str,
-    attrs: &[ast::Attribute],
-    bounds: &[Path<'_>],
-    self_ident: Ident,
-    self_generics: &Generics,
-) -> ast::GenericParam {
-    let bounds = bounds
-        .iter()
-        .map(|b| {
-            let path = b.to_path(cx, span, self_ident, self_generics);
-            cx.trait_bound(path)
-        })
-        .collect();
-    cx.typaram(span, cx.ident_of(name, span), attrs.to_owned(), bounds, None)
-}
-
-fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
-    Generics { params, where_clause: ast::WhereClause { predicates: Vec::new(), span }, span }
-}
-
-/// Lifetimes and bounds on type parameters
-#[derive(Clone)]
-pub struct LifetimeBounds<'a> {
-    pub lifetimes: Vec<(&'a str, Vec<&'a str>)>,
-    pub bounds: Vec<(&'a str, Vec<Path<'a>>)>,
-}
-
-impl<'a> LifetimeBounds<'a> {
-    pub fn empty() -> LifetimeBounds<'a> {
-        LifetimeBounds { lifetimes: Vec::new(), bounds: Vec::new() }
-    }
-    pub fn to_generics(
-        &self,
-        cx: &ExtCtxt<'_>,
-        span: Span,
-        self_ty: Ident,
-        self_generics: &Generics,
-    ) -> Generics {
-        let generic_params = self
-            .lifetimes
-            .iter()
-            .map(|&(lt, ref bounds)| {
-                let bounds = bounds
-                    .iter()
-                    .map(|b| ast::GenericBound::Outlives(cx.lifetime(span, Ident::from_str(b))));
-                cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds.collect())
-            })
-            .chain(self.bounds.iter().map(|t| {
-                let (name, ref bounds) = *t;
-                mk_ty_param(cx, span, name, &[], &bounds, self_ty, self_generics)
-            }))
-            .collect();
-
-        mk_generics(generic_params, span)
-    }
-}
-
-pub fn get_explicit_self(
-    cx: &ExtCtxt<'_>,
-    span: Span,
-    self_ptr: &Option<PtrTy>,
-) -> (P<Expr>, ast::ExplicitSelf) {
-    // this constructs a fresh `self` path
-    let self_path = cx.expr_self(span);
-    match *self_ptr {
-        None => (self_path, respan(span, SelfKind::Value(ast::Mutability::Not))),
-        Some(ref ptr) => {
-            let self_ty = respan(
-                span,
-                match *ptr {
-                    Borrowed(ref lt, mutbl) => {
-                        let lt = lt.map(|s| cx.lifetime(span, s));
-                        SelfKind::Region(lt, mutbl)
-                    }
-                    Raw(_) => cx.span_bug(span, "attempted to use *self in deriving definition"),
-                },
-            );
-            let self_expr = cx.expr_deref(span, self_path);
-            (self_expr, self_ty)
-        }
-    }
-}