use std::vec;
use syntax::abi::Abi;
-use syntax::ast::{self, EnumDef, Expr, Ident, Generics, VariantData, BinOpKind, PatKind};
+use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind, VariantData};
use syntax::attr;
use syntax::attr::AttrMetaMethods;
-use syntax::ext::base::{ExtCtxt, Annotatable};
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::codemap::{self, respan};
use syntax::util::move_map::MoveMap;
-use syntax::parse::token::{keywords, InternedString};
+use syntax::parse::token::{InternedString, keywords};
use syntax::ptr::P;
-use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::{DUMMY_SP, Span};
use errors::Handler;
use self::ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty};
pub self_args: &'a [P<Expr>],
/// verbatim access to any other arguments
pub nonself_args: &'a [P<Expr>],
- pub fields: &'a SubstructureFields<'a>
+ pub fields: &'a SubstructureFields<'a>,
}
/// Summary of the relevant parts of a struct/enum field.
Box<FnMut(&mut ExtCtxt, Span, (&[Ident], &[Ident]), &[P<Expr>]) -> P<Expr> + 'a>;
pub fn combine_substructure<'a>(f: CombineSubstructureFunc<'a>)
- -> RefCell<CombineSubstructureFunc<'a>> {
+ -> RefCell<CombineSubstructureFunc<'a>> {
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], span: Span, cx: &ExtCtxt)
+fn find_type_parameters(ty: &ast::Ty,
+ ty_param_names: &[ast::Name],
+ span: Span,
+ cx: &ExtCtxt)
-> Vec<P<ast::Ty>> {
use syntax::visit;
cx: &mut ExtCtxt,
mitem: &ast::MetaItem,
item: &'a Annotatable,
- push: &mut FnMut(Annotatable))
- {
+ push: &mut FnMut(Annotatable)) {
match *item {
Annotatable::Item(ref item) => {
let newitem = match item.node {
ast::ItemKind::Struct(ref struct_def, ref generics) => {
- self.expand_struct_def(cx,
- &struct_def,
- item.ident,
- generics)
+ self.expand_struct_def(cx, &struct_def, item.ident, generics)
}
ast::ItemKind::Enum(ref enum_def, ref generics) => {
- self.expand_enum_def(cx,
- enum_def,
- &item.attrs,
- item.ident,
- generics)
+ self.expand_enum_def(cx, enum_def, &item.attrs, item.ident, generics)
}
_ => {
cx.span_err(mitem.span,
// 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| {
- match &a.name()[..] {
- "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
- _ => false,
- }
- }).cloned());
- push(Annotatable::Item(P(ast::Item {
- attrs: attrs,
- ..(*newitem).clone()
- })))
+ attrs.extend(item.attrs
+ .iter()
+ .filter(|a| {
+ match &a.name()[..] {
+ "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
+ _ => false,
+ }
+ })
+ .cloned());
+ push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() })))
}
_ => {
- cx.span_err(mitem.span, "`derive` may only be applied to structs and enums");
+ cx.span_err(mitem.span,
+ "`derive` may only be applied to structs and enums");
}
}
}
type_ident: Ident,
generics: &Generics,
field_tys: Vec<P<ast::Ty>>,
- methods: Vec<ast::ImplItem>) -> P<ast::Item> {
+ methods: Vec<ast::ImplItem>)
+ -> P<ast::Item> {
let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
// Transform associated types from `deriving::ty::Ty` into `ast::ImplItem`
vis: ast::Visibility::Inherited,
defaultness: ast::Defaultness::Final,
attrs: Vec::new(),
- node: ast::ImplItemKind::Type(type_def.to_ty(cx,
- self.span,
- type_ident,
- generics
- )),
+ node: ast::ImplItemKind::Type(type_def.to_ty(cx, self.span, type_ident, generics)),
}
});
- let Generics { mut lifetimes, ty_params, mut where_clause } =
- self.generics.to_generics(cx, self.span, type_ident, generics);
+ let Generics { mut lifetimes, ty_params, mut where_clause } = self.generics
+ .to_generics(cx, self.span, type_ident, generics);
let mut ty_params = ty_params.into_vec();
// Copy the lifetimes
bounds.push((*declared_bound).clone());
}
- cx.typaram(self.span,
- ty_param.ident,
- P::from_vec(bounds),
- None)
+ cx.typaram(self.span, ty_param.ident, P::from_vec(bounds), None)
}));
// and similarly for where clauses
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
span: self.span,
lifetime: rb.lifetime,
- bounds: rb.bounds.iter().cloned().collect()
+ bounds: rb.bounds.iter().cloned().collect(),
})
}
ast::WherePredicate::EqPredicate(ref we) => {
id: ast::DUMMY_NODE_ID,
span: self.span,
path: we.path.clone(),
- ty: we.ty.clone()
+ ty: we.ty.clone(),
})
}
}
for ty in tys {
// 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].identifier.name)
- || processed_field_types.contains(&p.segments) {
+ if p.segments.len() == 1 &&
+ ty_param_names.contains(&p.segments[0].identifier.name) ||
+ processed_field_types.contains(&p.segments) {
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))
- }).collect();
+ let mut bounds: Vec<_> = 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()));
let trait_generics = Generics {
lifetimes: lifetimes,
ty_params: P::from_vec(ty_params),
- where_clause: where_clause
+ where_clause: where_clause,
};
// 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.ty_params.iter().map(|ty_param| {
- cx.ty_ident(self.span, ty_param.ident)
- }).collect();
+ let self_ty_params = generics.ty_params
+ .iter()
+ .map(|ty_param| cx.ty_ident(self.span, ty_param.ident))
+ .collect();
- let self_lifetimes: Vec<ast::Lifetime> =
- generics.lifetimes
+ let self_lifetimes: Vec<ast::Lifetime> = generics.lifetimes
.iter()
.map(|ld| ld.lifetime)
.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 attr = cx.attribute(
- self.span,
- cx.meta_word(self.span,
- InternedString::new("automatically_derived")));
+ let self_type = cx.ty_path(cx.path_all(self.span,
+ false,
+ vec![type_ident],
+ self_lifetimes,
+ self_ty_params,
+ Vec::new()));
+
+ let attr = cx.attribute(self.span,
+ cx.meta_word(self.span,
+ InternedString::new("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 = cx.attribute(
- self.span,
- cx.meta_list(self.span,
- InternedString::new("allow"),
- vec![cx.meta_word(self.span,
+ let unused_qual = cx.attribute(self.span,
+ cx.meta_list(self.span,
+ InternedString::new("allow"),
+ vec![cx.meta_word(self.span,
InternedString::new("unused_qualifications"))]));
let mut a = vec![attr, unused_qual];
a.extend(self.attributes.iter().cloned());
ast::Unsafety::Normal
};
- cx.item(
- self.span,
- keywords::Invalid.ident(),
- a,
- ast::ItemKind::Impl(unsafety,
- ast::ImplPolarity::Positive,
- trait_generics,
- opt_trait_ref,
- self_type,
- methods.into_iter().chain(associated_types).collect()))
+ cx.item(self.span,
+ keywords::Invalid.ident(),
+ a,
+ ast::ItemKind::Impl(unsafety,
+ ast::ImplPolarity::Positive,
+ trait_generics,
+ opt_trait_ref,
+ self_type,
+ methods.into_iter().chain(associated_types).collect()))
}
fn expand_struct_def(&self,
cx: &mut ExtCtxt,
struct_def: &'a VariantData,
type_ident: Ident,
- generics: &Generics) -> P<ast::Item> {
- let field_tys: Vec<P<ast::Ty>> = struct_def.fields().iter()
+ generics: &Generics)
+ -> 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 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[..])
- };
-
- method_def.create_method(cx,
- self,
- type_ident,
- generics,
- Abi::Rust,
- explicit_self,
- tys,
- body)
- }).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 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[..])
+ };
+
+ method_def.create_method(cx,
+ self,
+ type_ident,
+ generics,
+ Abi::Rust,
+ explicit_self,
+ tys,
+ body)
+ })
+ .collect();
self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
}
enum_def: &'a EnumDef,
type_attrs: &[ast::Attribute],
type_ident: Ident,
- generics: &Generics) -> P<ast::Item> {
+ generics: &Generics)
+ -> P<ast::Item> {
let mut field_tys = Vec::new();
for variant in &enum_def.variants {
- field_tys.extend(variant.node.data.fields().iter()
+ field_tys.extend(variant.node
+ .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 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,
- Abi::Rust,
- explicit_self,
- tys,
- body)
- }).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 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,
+ Abi::Rust,
+ explicit_self,
+ tys,
+ body)
+ })
+ .collect();
self.create_derived_impl(cx, type_ident, generics, field_tys, methods)
}
}
-fn find_repr_type_name(diagnostic: &Handler,
- type_attrs: &[ast::Attribute]) -> &'static str {
+fn find_repr_type_name(diagnostic: &Handler, type_attrs: &[ast::Attribute]) -> &'static str {
let mut repr_type_name = "isize";
for a in type_attrs {
for r in &attr::find_repr_attrs(diagnostic, a) {
self_args: &[P<Expr>],
nonself_args: &[P<Expr>],
fields: &SubstructureFields)
- -> P<Expr> {
+ -> P<Expr> {
let substructure = Substructure {
type_ident: type_ident,
method_ident: cx.ident_of(self.name),
self_args: self_args,
nonself_args: nonself_args,
- fields: fields
+ fields: fields,
};
let mut f = self.combine_substructure.borrow_mut();
let f: &mut CombineSubstructureFunc = &mut *f;
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>)>) {
+ 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();
match *ty {
// for static methods, just treat any Self
// arguments as a normal arg
- Self_ if nonstatic => {
+ Self_ if nonstatic => {
self_args.push(arg_expr);
}
Ptr(ref ty, _) if **ty == Self_ && nonstatic => {
generics: &Generics,
abi: Abi,
explicit_self: Option<ast::ExplicitSelf>,
- arg_types: Vec<(Ident, P<ast::Ty>)> ,
- body: P<Expr>) -> ast::ImplItem {
+ arg_types: Vec<(Ident, P<ast::Ty>)>,
+ body: P<Expr>)
+ -> ast::ImplItem {
// create the generics that aren't for Self
let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics);
let args = {
let self_args = explicit_self.map(|explicit_self| {
- ast::Arg::from_self(explicit_self, respan(trait_.span, keywords::SelfValue.ident()))
+ ast::Arg::from_self(explicit_self,
+ respan(trait_.span, keywords::SelfValue.ident()))
});
let nonself_args = arg_types.into_iter()
- .map(|(name, ty)| cx.arg(trait_.span, name, ty));
+ .map(|(name, ty)| cx.arg(trait_.span, name, ty));
self_args.into_iter().chain(nonself_args).collect()
};
defaultness: ast::Defaultness::Final,
ident: method_ident,
node: ast::ImplItemKind::Method(ast::MethodSig {
- generics: fn_generics,
- abi: abi,
- unsafety: unsafety,
- constness: ast::Constness::NotConst,
- decl: fn_decl
- }, body_block)
+ generics: fn_generics,
+ abi: abi,
+ unsafety: unsafety,
+ constness: ast::Constness::NotConst,
+ decl: fn_decl,
+ },
+ body_block),
}
}
/// }
/// ```
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>])
- -> P<Expr> {
+ cx: &mut ExtCtxt,
+ trait_: &TraitDef<'b>,
+ struct_def: &'b VariantData,
+ type_ident: Ident,
+ self_args: &[P<Expr>],
+ nonself_args: &[P<Expr>])
+ -> 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(DUMMY_SP, vec!( type_ident ));
- let (pat, ident_expr) =
- trait_.create_struct_pattern(cx,
- struct_path,
- struct_def,
- &format!("__self_{}",
- i),
- ast::Mutability::Immutable);
+ let struct_path = cx.path(DUMMY_SP, vec![type_ident]);
+ let (pat, ident_expr) = trait_.create_struct_pattern(cx,
+ struct_path,
+ struct_def,
+ &format!("__self_{}", i),
+ ast::Mutability::Immutable);
patterns.push(pat);
raw_fields.push(ident_expr);
}
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();
+ let mut other_fields: Vec<vec::IntoIter<_>> = raw_fields.collect();
first_field.map(|(span, opt_id, field, attrs)| {
- FieldInfo {
- span: span,
- name: opt_id,
- self_: field,
- other: other_fields.iter_mut().map(|l| {
- match l.next().unwrap() {
- (_, _, ex, _) => ex
- }
- }).collect(),
- attrs: attrs,
- }
- }).collect()
+ FieldInfo {
+ span: span,
+ name: opt_id,
+ self_: field,
+ other: other_fields.iter_mut()
+ .map(|l| {
+ match l.next().unwrap() {
+ (_, _, ex, _) => ex,
+ }
+ })
+ .collect(),
+ attrs: attrs,
+ }
+ })
+ .collect()
} else {
cx.span_bug(trait_.span,
"no self arguments to non-static method in generic \
};
// 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));
+ 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, vec!(pat.clone()), body) ))
+ body = cx.expr_match(trait_.span,
+ arg_expr.clone(),
+ vec![cx.arm(trait_.span, vec![pat.clone()], body)])
}
body
type_ident: Ident,
self_args: &[P<Expr>],
nonself_args: &[P<Expr>])
- -> P<Expr> {
+ -> P<Expr> {
let summary = trait_.summarise_struct(cx, struct_def);
self.call_substructure_method(cx,
trait_,
type_ident,
- self_args, nonself_args,
+ self_args,
+ nonself_args,
&StaticStruct(struct_def, summary))
}
/// 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)
+ 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)
}
/// ... // 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,
- self_args: Vec<P<Expr>>,
- nonself_args: &[P<Expr>]) -> P<Expr> {
+ fn build_enum_match_tuple<'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> {
let sp = trait_.span;
let variants = &enum_def.variants;
- let self_arg_names = self_args.iter().enumerate()
+ let self_arg_names = self_args.iter()
+ .enumerate()
.map(|(arg_count, _self_arg)| {
if arg_count == 0 {
"__self".to_string()
.collect::<Vec<String>>();
let self_arg_idents = self_arg_names.iter()
- .map(|name|cx.ident_of(&name[..]))
+ .map(|name| cx.ident_of(&name[..]))
.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: Vec<ast::Ident> = self_arg_names.iter()
- .map(|name| { let vi_suffix = format!("{}_vi", &name[..]);
- cx.ident_of(&vi_suffix[..]) })
+ .map(|name| {
+ let vi_suffix = format!("{}_vi", &name[..]);
+ cx.ident_of(&vi_suffix[..])
+ })
.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 catch_all_substructure =
+ EnumNonMatchingCollapsed(self_arg_idents, &variants[..], &vi_idents[..]);
let first_fieldless = variants.iter().find(|v| v.node.data.fields().is_empty());
// (Variant2, Variant2, ...) => Body2
// ...
// where each tuple has length = self_args.len()
- let mut match_arms: Vec<ast::Arm> = variants.iter().enumerate()
+ let mut match_arms: Vec<ast::Arm> = variants.iter()
+ .enumerate()
.filter(|&(_, v)| !(self.unify_fieldless_variants && v.node.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::Immutable);
+ let (p, idents) = trait_.create_enum_variant_pattern(cx,
+ type_ident,
+ variant,
+ self_arg_name,
+ ast::Mutability::Immutable);
(cx.pat(sp, PatKind::Ref(p, ast::Mutability::Immutable)), idents)
};
// 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,
- variant,
- field_tuples);
- let arm_expr = self.call_substructure_method(
- cx, trait_, type_ident, &self_args[..], nonself_args,
- &substructure);
+ let substructure = EnumMatching(index, variant, field_tuples);
+ let arm_expr = self.call_substructure_method(cx,
+ trait_,
+ type_ident,
+ &self_args[..],
+ nonself_args,
+ &substructure);
cx.arm(sp, vec![single_pat], arm_expr)
- }).collect();
+ })
+ .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
- Some(self.call_substructure_method(
- cx, trait_, type_ident, &self_args[..], nonself_args,
- &EnumMatching(0, v, Vec::new())))
+ Some(self.call_substructure_method(cx,
+ trait_,
+ type_ident,
+ &self_args[..],
+ nonself_args,
+ &EnumMatching(0, v, Vec::new())))
}
_ if variants.len() > 1 && self_args.len() > 1 => {
// Since we know that all the arguments will match if we reach
// result of the catch all which should help llvm in optimizing it
Some(deriving::call_intrinsic(cx, sp, "unreachable", vec![]))
}
- _ => None
+ _ => None,
};
if let Some(arm) = default {
match_arms.push(cx.arm(sp, vec![cx.pat_wild(sp)], arm));
// ```
let mut index_let_stmts: Vec<ast::Stmt> = Vec::new();
- //We also build an expression which checks whether all discriminants are equal
+ // 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.span_diagnostic, type_attrs);
+ let target_type_name = find_repr_type_name(&cx.parse_sess.span_diagnostic, 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 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));
let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
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)
+ 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);
+ 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 l-values, but we cannot actually deref
let borrowed_self_args = self_args.move_map(|self_arg| cx.expr_addr_of(sp, self_arg));
let match_arg = cx.expr(sp, ast::ExprKind::Tup(borrowed_self_args));
- //Lastly we create an expression which branches on all discriminants being equal
+ // Lastly we create an expression which branches on all discriminants being equal
// if discriminant_test {
// match (...) {
// (Variant1, Variant1, ...) => Body1
// that needs the feature gate enabled.)
deriving::call_intrinsic(cx, sp, "unreachable", vec![])
- }
- else {
+ } else {
// Final wrinkle: the self_args are expressions that deref
// down to desired l-values, but we cannot actually deref
type_ident: Ident,
self_args: &[P<Expr>],
nonself_args: &[P<Expr>])
- -> P<Expr> {
- let summary = enum_def.variants.iter().map(|v| {
- let ident = v.node.name;
- let summary = trait_.summarise_struct(cx, &v.node.data);
- (ident, v.span, summary)
- }).collect();
- self.call_substructure_method(cx, trait_, type_ident,
- self_args, nonself_args,
+ -> P<Expr> {
+ let summary = enum_def.variants
+ .iter()
+ .map(|v| {
+ let ident = v.node.name;
+ let summary = trait_.summarise_struct(cx, &v.node.data);
+ (ident, v.span, 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 {
+ 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(){
+ for field in struct_def.fields() {
let sp = Span { expn_id: self.span.expn_id, ..field.span };
match field.ident {
Some(ident) => named_idents.push((ident, sp)),
}
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`"),
+ (false, false) => {
+ cx.span_bug(self.span,
+ "a struct with named and unnamed \
+ fields in generic `derive`")
+ }
// named fields
(_, false) => Named(named_idents),
// empty structs
fn create_subpatterns(&self,
cx: &mut ExtCtxt,
- field_paths: Vec<ast::SpannedIdent> ,
+ field_paths: Vec<ast::SpannedIdent>,
mutbl: ast::Mutability)
-> Vec<P<ast::Pat>> {
- field_paths.iter().map(|path| {
- cx.pat(path.span,
- PatKind::Ident(ast::BindingMode::ByRef(mutbl), (*path).clone(), None))
- }).collect()
+ field_paths.iter()
+ .map(|path| {
+ cx.pat(path.span,
+ PatKind::Ident(ast::BindingMode::ByRef(mutbl), (*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)
- -> (P<ast::Pat>, Vec<(Span, Option<Ident>,
- P<Expr>,
- &'a [ast::Attribute])>) {
+ fn create_struct_pattern
+ (&self,
+ cx: &mut ExtCtxt,
+ struct_path: ast::Path,
+ struct_def: &'a VariantData,
+ prefix: &str,
+ mutbl: ast::Mutability)
+ -> (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 = Span { expn_id: self.span.expn_id, ..struct_field.span };
let ident = cx.ident_of(&format!("{}_{}", prefix, i));
- paths.push(codemap::Spanned{span: sp, node: ident});
- let val = cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident)));
+ paths.push(codemap::Spanned {
+ span: sp,
+ node: ident,
+ });
+ let val = cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp, ident)));
let val = cx.expr(sp, ast::ExprKind::Paren(val));
ident_exprs.push((sp, struct_field.ident, val, &struct_field.attrs[..]));
}
let subpats = self.create_subpatterns(cx, paths, mutbl);
let pattern = if struct_def.is_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`");
- }
- codemap::Spanned {
- span: pat.span,
- node: ast::FieldPat { ident: ident.unwrap(), pat: pat, is_shorthand: false },
- }
- }).collect();
+ 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`");
+ }
+ codemap::Spanned {
+ span: pat.span,
+ node: ast::FieldPat {
+ ident: ident.unwrap(),
+ pat: pat,
+ is_shorthand: false,
+ },
+ }
+ })
+ .collect();
cx.pat_struct(self.span, struct_path, field_pats)
} else {
cx.pat_enum(self.span, struct_path, subpats)
(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])>) {
+ 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 variant_ident = variant.node.name;
let variant_path = cx.path(variant.span, vec![enum_ident, variant_ident]);
self.create_struct_pattern(cx, variant_path, &variant.node.data, prefix, mutbl)
}
}
-/* helpful premade recipes */
+// helpful premade recipes
/// Fold the fields. `use_foldl` controls whether this is done
/// left-to-right (`true`) or right-to-left (`false`).
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
- -> P<Expr> where
- F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
+ -> 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) => {
+ EnumMatching(_, _, ref all_fields) |
+ Struct(_, ref all_fields) => {
if use_foldl {
all_fields.iter().fold(base, |old, field| {
- f(cx,
- field.span,
- old,
- field.self_.clone(),
- &field.other)
+ 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)
+ f(cx, field.span, old, field.self_.clone(), &field.other)
})
}
- },
- EnumNonMatchingCollapsed(ref all_args, _, tuple) =>
- enum_nonmatch_f(cx, trait_span, (&all_args[..], tuple),
- substructure.nonself_args),
- StaticEnum(..) | StaticStruct(..) => {
- cx.span_bug(trait_span, "static function in `derive`")
}
+ EnumNonMatchingCollapsed(ref all_args, _, tuple) => {
+ enum_nonmatch_f(cx,
+ trait_span,
+ (&all_args[..], tuple),
+ substructure.nonself_args)
+ }
+ StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"),
}
}
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
- -> P<Expr> where
- F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>,
+ -> P<Expr>
+ where F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>
{
match *substructure.fields {
- EnumMatching(_, _, ref all_fields) | Struct(_, ref all_fields) => {
+ EnumMatching(_, _, ref all_fields) |
+ Struct(_, ref all_fields) => {
// call self_n.method(other_1_n, other_2_n, ...)
- let called = all_fields.iter().map(|field| {
- cx.expr_method_call(field.span,
- field.self_.clone(),
- substructure.method_ident,
- field.other.iter()
- .map(|e| cx.expr_addr_of(field.span, e.clone()))
- .collect())
- }).collect();
+ let called = all_fields.iter()
+ .map(|field| {
+ cx.expr_method_call(field.span,
+ field.self_.clone(),
+ substructure.method_ident,
+ field.other
+ .iter()
+ .map(|e| cx.expr_addr_of(field.span, e.clone()))
+ .collect())
+ })
+ .collect();
f(cx, trait_span, called)
- },
- EnumNonMatchingCollapsed(ref all_self_args, _, tuple) =>
- enum_nonmatch_f(cx, trait_span, (&all_self_args[..], tuple),
- substructure.nonself_args),
- StaticEnum(..) | StaticStruct(..) => {
- cx.span_bug(trait_span, "static function in `derive`")
}
+ EnumNonMatchingCollapsed(ref all_self_args, _, tuple) => {
+ enum_nonmatch_f(cx,
+ trait_span,
+ (&all_self_args[..], tuple),
+ substructure.nonself_args)
+ }
+ StaticEnum(..) | StaticStruct(..) => cx.span_bug(trait_span, "static function in `derive`"),
}
}
ast::ItemKind::Enum(ref enum_def, _) => {
enum_def.variants.iter().all(|v| v.node.data.fields().is_empty())
}
- ast::ItemKind::Struct(ref variant_data, _) => {
- variant_data.fields().is_empty()
- }
- _ => false
+ ast::ItemKind::Struct(ref variant_data, _) => variant_data.fields().is_empty(),
+ _ => false,
}
} else {
false