From ede7a6dc8ff5455f9d0d39a90e6d11e9a374e93b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 1 May 2015 06:40:06 +0530 Subject: Give access to field attributes in ext::deriving --- src/libsyntax/ext/deriving/generic/mod.rs | 62 ++++++++++++++++--------------- 1 file changed, 33 insertions(+), 29 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 4c05cd973ff..22f62d9efa0 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -270,7 +270,7 @@ pub struct Substructure<'a> { } /// Summary of the relevant parts of a struct/enum field. -pub struct FieldInfo { +pub struct FieldInfo<'a> { pub span: Span, /// None for tuple structs/normal enum variants, Some for normal /// structs/struct enum variants. @@ -281,6 +281,8 @@ pub struct FieldInfo { /// The expressions corresponding to references to this field in /// the other `Self` arguments. pub other: Vec>, + /// The attributes on the field + pub attrs: &'a [ast::Attribute], } /// Fields for a static method @@ -293,11 +295,11 @@ pub enum StaticFields { /// A summary of the possible sets of fields. pub enum SubstructureFields<'a> { - Struct(Vec), + Struct(Vec>), /// Matching variants of the enum: variant index, ast::Variant, /// fields: the field name is only non-`None` in the case of a struct /// variant. - EnumMatching(usize, &'a ast::Variant, Vec), + EnumMatching(usize, &'a ast::Variant, Vec>), /// Non-matching variants of the enum, but with all state hidden from /// the consequent code. The first component holds `Ident`s for all of @@ -378,7 +380,7 @@ impl<'a> TraitDef<'a> { pub fn expand(&self, cx: &mut ExtCtxt, mitem: &ast::MetaItem, - item: &ast::Item, + item: &'a ast::Item, push: &mut FnMut(P)) { let newitem = match item.node { @@ -609,7 +611,7 @@ impl<'a> TraitDef<'a> { fn expand_struct_def(&self, cx: &mut ExtCtxt, - struct_def: &StructDef, + struct_def: &'a StructDef, type_ident: Ident, generics: &Generics) -> P { let field_tys: Vec> = struct_def.fields.iter() @@ -653,7 +655,7 @@ impl<'a> TraitDef<'a> { fn expand_enum_def(&self, cx: &mut ExtCtxt, - enum_def: &EnumDef, + enum_def: &'a EnumDef, type_attrs: &[ast::Attribute], type_ident: Ident, generics: &Generics) -> P { @@ -885,10 +887,10 @@ impl<'a> MethodDef<'a> { /// } /// } /// ``` - fn expand_struct_method_body(&self, + fn expand_struct_method_body<'b>(&self, cx: &mut ExtCtxt, - trait_: &TraitDef, - struct_def: &StructDef, + trait_: &TraitDef<'b>, + struct_def: &'b StructDef, type_ident: Ident, self_args: &[P], nonself_args: &[P]) @@ -914,18 +916,19 @@ impl<'a> MethodDef<'a> { 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, P)>> + let mut other_fields: Vec> = raw_fields.collect(); - first_field.map(|(span, opt_id, field)| { + 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 + (_, _, ex, _) => ex } - }).collect() + }).collect(), + attrs: attrs, } }).collect() } else { @@ -999,10 +1002,10 @@ impl<'a> MethodDef<'a> { /// `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(&self, + fn expand_enum_method_body<'b>(&self, cx: &mut ExtCtxt, - trait_: &TraitDef, - enum_def: &EnumDef, + trait_: &TraitDef<'b>, + enum_def: &'b EnumDef, type_attrs: &[ast::Attribute], type_ident: Ident, self_args: Vec>, @@ -1038,11 +1041,11 @@ impl<'a> MethodDef<'a> { /// } /// } /// ``` - fn build_enum_match_tuple( + fn build_enum_match_tuple<'b>( &self, cx: &mut ExtCtxt, - trait_: &TraitDef, - enum_def: &EnumDef, + trait_: &TraitDef<'b>, + enum_def: &'b EnumDef, type_attrs: &[ast::Attribute], type_ident: Ident, self_args: Vec>, @@ -1125,7 +1128,7 @@ impl<'a> MethodDef<'a> { // 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))| { + .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 @@ -1133,7 +1136,7 @@ impl<'a> MethodDef<'a> { // 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) = + let (_, _opt_ident, ref other_getter_expr, _) = fields[field_index]; // All Self args have same variant, so @@ -1149,6 +1152,7 @@ impl<'a> MethodDef<'a> { name: opt_ident, self_: self_getter_expr, other: others, + attrs: attrs, } }).collect::>(); @@ -1400,10 +1404,10 @@ impl<'a> TraitDef<'a> { fn create_struct_pattern(&self, cx: &mut ExtCtxt, struct_path: ast::Path, - struct_def: &StructDef, + struct_def: &'a StructDef, prefix: &str, mutbl: ast::Mutability) - -> (P, Vec<(Span, Option, P)>) { + -> (P, Vec<(Span, Option, P, &'a [ast::Attribute])>) { if struct_def.fields.is_empty() { return (cx.pat_enum(self.span, struct_path, vec![]), vec![]); } @@ -1433,7 +1437,7 @@ impl<'a> TraitDef<'a> { paths.push(codemap::Spanned{span: sp, node: ident}); let val = cx.expr( sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident))))); - ident_expr.push((sp, opt_id, val)); + ident_expr.push((sp, opt_id, val, &struct_field.node.attrs[..])); } let subpats = self.create_subpatterns(cx, paths, mutbl); @@ -1441,7 +1445,7 @@ impl<'a> TraitDef<'a> { // struct_type is definitely not Unknown, since struct_def.fields // must be nonempty to reach here let pattern = if struct_type == Record { - let field_pats = subpats.into_iter().zip(ident_expr.iter()).map(|(pat, &(_, id, _))| { + let field_pats = subpats.into_iter().zip(ident_expr.iter()).map(|(pat, &(_, id, _, _))| { // id is guaranteed to be Some codemap::Spanned { span: pat.span, @@ -1459,10 +1463,10 @@ impl<'a> TraitDef<'a> { fn create_enum_variant_pattern(&self, cx: &mut ExtCtxt, enum_ident: ast::Ident, - variant: &ast::Variant, + variant: &'a ast::Variant, prefix: &str, mutbl: ast::Mutability) - -> (P, Vec<(Span, Option, P)>) { + -> (P, Vec<(Span, Option, P, &'a [ast::Attribute])>) { let variant_ident = variant.node.name; let variant_path = cx.path(variant.span, vec![enum_ident, variant_ident]); match variant.node.kind { @@ -1472,7 +1476,7 @@ impl<'a> TraitDef<'a> { } let mut paths = Vec::new(); - let mut ident_expr = Vec::new(); + let mut ident_expr: Vec<(_, _, _, &'a [ast::Attribute])> = Vec::new(); for (i, va) in variant_args.iter().enumerate() { let sp = self.set_expn_info(cx, va.ty.span); let ident = cx.ident_of(&format!("{}_{}", prefix, i)); @@ -1480,7 +1484,7 @@ impl<'a> TraitDef<'a> { paths.push(path1); let expr_path = cx.expr_path(cx.path_ident(sp, ident)); let val = cx.expr(sp, ast::ExprParen(cx.expr_deref(sp, expr_path))); - ident_expr.push((sp, None, val)); + ident_expr.push((sp, None, val, &[])); } let subpats = self.create_subpatterns(cx, paths, mutbl); -- cgit 1.4.1-3-g733a5 From 5892b40859b65dd520ae92f7570069adaf313a8f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 1 May 2015 15:52:38 +0530 Subject: Rename AstBuilder::expr_int -> AstBuilder::expr_isize --- src/libsyntax/ext/build.rs | 4 ++-- src/libsyntax/ext/deriving/generic/mod.rs | 9 ++++++--- src/test/auxiliary/custom_derive_plugin.rs | 2 +- src/test/auxiliary/custom_derive_plugin_attr.rs | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index cde16d25412..354a0bff749 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -146,7 +146,7 @@ pub trait AstBuilder { fn expr_lit(&self, sp: Span, lit: ast::Lit_) -> P; fn expr_usize(&self, span: Span, i: usize) -> P; - fn expr_int(&self, sp: Span, i: isize) -> P; + fn expr_isize(&self, sp: Span, i: isize) -> P; fn expr_u8(&self, sp: Span, u: u8) -> P; fn expr_u32(&self, sp: Span, u: u32) -> P; fn expr_bool(&self, sp: Span, value: bool) -> P; @@ -698,7 +698,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn expr_usize(&self, span: Span, i: usize) -> P { self.expr_lit(span, ast::LitInt(i as u64, ast::UnsignedIntLit(ast::TyUs))) } - fn expr_int(&self, sp: Span, i: isize) -> P { + fn expr_isize(&self, sp: Span, i: isize) -> P { self.expr_lit(sp, ast::LitInt(i as u64, ast::SignedIntLit(ast::TyIs, ast::Sign::new(i)))) } diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 22f62d9efa0..339e535cdcd 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -380,7 +380,7 @@ impl<'a> TraitDef<'a> { pub fn expand(&self, cx: &mut ExtCtxt, mitem: &ast::MetaItem, - item: &'a ast::Item, + item: &'a ast::Item, push: &mut FnMut(P)) { let newitem = match item.node { @@ -1407,7 +1407,9 @@ impl<'a> TraitDef<'a> { struct_def: &'a StructDef, prefix: &str, mutbl: ast::Mutability) - -> (P, Vec<(Span, Option, P, &'a [ast::Attribute])>) { + -> (P, Vec<(Span, Option, + P, + &'a [ast::Attribute])>) { if struct_def.fields.is_empty() { return (cx.pat_enum(self.span, struct_path, vec![]), vec![]); } @@ -1445,7 +1447,8 @@ impl<'a> TraitDef<'a> { // struct_type is definitely not Unknown, since struct_def.fields // must be nonempty to reach here let pattern = if struct_type == Record { - let field_pats = subpats.into_iter().zip(ident_expr.iter()).map(|(pat, &(_, id, _, _))| { + let field_pats = subpats.into_iter().zip(ident_expr.iter()) + .map(|(pat, &(_, id, _, _))| { // id is guaranteed to be Some codemap::Spanned { span: pat.span, diff --git a/src/test/auxiliary/custom_derive_plugin.rs b/src/test/auxiliary/custom_derive_plugin.rs index 17d3f6a46ef..78381395dc9 100644 --- a/src/test/auxiliary/custom_derive_plugin.rs +++ b/src/test/auxiliary/custom_derive_plugin.rs @@ -55,7 +55,7 @@ fn expand(cx: &mut ExtCtxt, ret_ty: Literal(Path::new_local("isize")), attributes: vec![], combine_substructure: combine_substructure(box |cx, span, substr| { - let zero = cx.expr_int(span, 0); + let zero = cx.expr_isize(span, 0); cs_fold(false, |cx, span, subexpr, field, _| { cx.expr_binary(span, ast::BiAdd, subexpr, diff --git a/src/test/auxiliary/custom_derive_plugin_attr.rs b/src/test/auxiliary/custom_derive_plugin_attr.rs index 631645ec0c0..445aa743a77 100644 --- a/src/test/auxiliary/custom_derive_plugin_attr.rs +++ b/src/test/auxiliary/custom_derive_plugin_attr.rs @@ -66,13 +66,14 @@ fn expand(cx: &mut ExtCtxt, // Mostly copied from syntax::ext::deriving::hash /// Defines how the implementation for `trace()` is to be generated -fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P { +fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span, + substr: &Substructure) -> P { let fields = match *substr.fields { Struct(ref fs) | EnumMatching(_, _, ref fs) => fs, _ => cx.span_bug(trait_span, "impossible substructure") }; - fields.iter().fold(cx.expr_int(trait_span, 0), |acc, ref item| { + fields.iter().fold(cx.expr_isize(trait_span, 0), |acc, ref item| { if item.attrs.iter().find(|a| a.check_name("ignore")).is_some() { acc } else { -- cgit 1.4.1-3-g733a5