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};
/// 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
/// 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>> {
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);
}
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) => {
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
.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)
}
}));
// 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();
.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);
// 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,
// 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,
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))
}
_ => {
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),