diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2013-12-07 11:57:44 +1100 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2013-12-07 11:57:44 +1100 |
| commit | 09a879460cfa42ecfd4a769bdc21e1d55b795bd8 (patch) | |
| tree | e8423abcddefb2fc8e102208910048646c6c46de /src/libsyntax | |
| parent | aa4455e4c76598fcf6de84de14f050a700a2a14e (diff) | |
| download | rust-09a879460cfa42ecfd4a769bdc21e1d55b795bd8.tar.gz rust-09a879460cfa42ecfd4a769bdc21e1d55b795bd8.zip | |
syntax::deriving: add the cx and span to the TraitDef to reduce duplication.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/deriving/clone.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/eq.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/ord.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/totaleq.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/totalord.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/decodable.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/default.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/encodable.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 421 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/iter_bytes.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/primitive.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/rand.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/to_str.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/zero.rs | 4 |
14 files changed, 251 insertions, 226 deletions
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index 0f83f725223..9285defe69e 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -20,6 +20,8 @@ pub fn expand_deriving_clone(cx: @ExtCtxt, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "clone", "Clone"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -37,7 +39,7 @@ pub fn expand_deriving_clone(cx: @ExtCtxt, ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } pub fn expand_deriving_deep_clone(cx: @ExtCtxt, @@ -46,6 +48,8 @@ pub fn expand_deriving_deep_clone(cx: @ExtCtxt, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "clone", "DeepClone"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -65,7 +69,7 @@ pub fn expand_deriving_deep_clone(cx: @ExtCtxt, ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } fn cs_clone( diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index eb07d2d209c..74680266cb7 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -45,6 +45,8 @@ pub fn expand_deriving_eq(cx: @ExtCtxt, ); let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "cmp", "Eq"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -53,5 +55,5 @@ pub fn expand_deriving_eq(cx: @ExtCtxt, md!("ne", cs_ne) ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index 95d617af0c7..d48cfbd7dd7 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -35,6 +35,8 @@ pub fn expand_deriving_ord(cx: @ExtCtxt, ); let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "cmp", "Ord"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -45,7 +47,7 @@ pub fn expand_deriving_ord(cx: @ExtCtxt, md!("ge", false, true) ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } /// Strict inequality. diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs index 51965e1b582..ab822d14b48 100644 --- a/src/libsyntax/ext/deriving/cmp/totaleq.rs +++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs @@ -24,6 +24,8 @@ pub fn expand_deriving_totaleq(cx: @ExtCtxt, } let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "cmp", "TotalEq"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -40,5 +42,5 @@ pub fn expand_deriving_totaleq(cx: @ExtCtxt, } ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs index 217acd98c68..2ace39a3486 100644 --- a/src/libsyntax/ext/deriving/cmp/totalord.rs +++ b/src/libsyntax/ext/deriving/cmp/totalord.rs @@ -21,6 +21,8 @@ pub fn expand_deriving_totalord(cx: @ExtCtxt, mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "cmp", "TotalOrd"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -38,7 +40,7 @@ pub fn expand_deriving_totalord(cx: @ExtCtxt, ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 4ab0cc3bc67..0aade760b7b 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -24,6 +24,8 @@ pub fn expand_deriving_decodable(cx: @ExtCtxt, mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new_(~["extra", "serialize", "Decodable"], None, ~[~Literal(Path::new_local("__D"))], true), additional_bounds: ~[], @@ -46,7 +48,7 @@ pub fn expand_deriving_decodable(cx: @ExtCtxt, ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } fn decodable_substructure(cx: @ExtCtxt, span: Span, diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs index 3ecdd5e60fe..393d808a025 100644 --- a/src/libsyntax/ext/deriving/default.rs +++ b/src/libsyntax/ext/deriving/default.rs @@ -20,6 +20,8 @@ pub fn expand_deriving_default(cx: @ExtCtxt, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "default", "Default"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -36,7 +38,7 @@ pub fn expand_deriving_default(cx: @ExtCtxt, }, ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } fn default_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr { diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 96b77c4c162..09210116c37 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -86,6 +86,8 @@ pub fn expand_deriving_encodable(cx: @ExtCtxt, mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new_(~["extra", "serialize", "Encodable"], None, ~[~Literal(Path::new_local("__E"))], true), additional_bounds: ~[], @@ -108,7 +110,7 @@ pub fn expand_deriving_encodable(cx: @ExtCtxt, ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } fn encodable_substructure(cx: @ExtCtxt, span: Span, diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 627e799f2d3..66f1e506ae8 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -179,7 +179,8 @@ use ast::{P, enum_def, Expr, Ident, Generics, struct_def}; use ext::base::ExtCtxt; use ext::build::AstBuilder; -use codemap::{Span,respan}; +use codemap; +use codemap::Span; use opt_vec; use std::vec; @@ -188,6 +189,11 @@ pub use self::ty::*; mod ty; pub struct TraitDef<'self> { + /// The extension context + cx: @ExtCtxt, + /// The span for the current #[deriving(Foo)] header. + span: Span, + /// Path of the trait, including any type parameters path: Path<'self>, /// Additional bounds required of any type parameters of the type, @@ -310,8 +316,7 @@ pub type EnumNonMatchFunc<'self> = impl<'self> TraitDef<'self> { - pub fn expand(&self, cx: @ExtCtxt, - trait_span: Span, + pub fn expand(&self, _mitem: @ast::MetaItem, in_items: ~[@ast::item]) -> ~[@ast::item] { let mut result = ~[]; @@ -319,14 +324,12 @@ impl<'self> TraitDef<'self> { result.push(*item); match item.node { ast::item_struct(struct_def, ref generics) => { - result.push(self.expand_struct_def(cx, trait_span, - struct_def, + result.push(self.expand_struct_def(struct_def, item.ident, generics)); } ast::item_enum(ref enum_def, ref generics) => { - result.push(self.expand_enum_def(cx, trait_span, - enum_def, + result.push(self.expand_enum_def(enum_def, item.ident, generics)); } @@ -346,12 +349,14 @@ impl<'self> TraitDef<'self> { * where B1, B2, ... are the bounds given by `bounds_paths`.' * */ - fn create_derived_impl(&self, cx: @ExtCtxt, trait_span: Span, + fn create_derived_impl(&self, type_ident: Ident, generics: &Generics, methods: ~[@ast::method]) -> @ast::item { - let trait_path = self.path.to_path(cx, trait_span, type_ident, generics); + let cx = self.cx; + let trait_path = self.path.to_path(cx, self.span, type_ident, generics); - let mut trait_generics = self.generics.to_generics(cx, trait_span, type_ident, generics); + let mut trait_generics = self.generics.to_generics(cx, self.span, + type_ident, generics); // Copy the lifetimes for l in generics.lifetimes.iter() { trait_generics.lifetimes.push(*l) @@ -363,7 +368,7 @@ impl<'self> TraitDef<'self> { let mut bounds = opt_vec::from( // extra restrictions on the generics parameters to the type being derived upon self.additional_bounds.map(|p| { - cx.typarambound(p.to_path(cx, trait_span, type_ident, generics)) + cx.typarambound(p.to_path(cx, self.span, type_ident, generics)) })); // require the current trait bounds.push(cx.typarambound(trait_path.clone())); @@ -376,22 +381,23 @@ impl<'self> TraitDef<'self> { // Create the type parameters on the `self` path. let self_ty_params = generics.ty_params.map(|ty_param| { - cx.ty_ident(trait_span, ty_param.ident) + cx.ty_ident(self.span, ty_param.ident) }); let self_lifetimes = generics.lifetimes.clone(); // Create the type of `self`. - let self_type = cx.ty_path(cx.path_all(trait_span, false, ~[ type_ident ], self_lifetimes, - opt_vec::take_vec(self_ty_params)), None); + let self_type = cx.ty_path( + cx.path_all(self.span, false, ~[ type_ident ], self_lifetimes, + opt_vec::take_vec(self_ty_params)), None); let doc_attr = cx.attribute( - trait_span, - cx.meta_name_value(trait_span, + self.span, + cx.meta_name_value(self.span, @"doc", ast::lit_str(@"Automatically derived.", ast::CookedStr))); cx.item( - trait_span, + self.span, ::parse::token::special_idents::clownshoes_extensions, ~[doc_attr], ast::item_impl(trait_generics, @@ -400,73 +406,70 @@ impl<'self> TraitDef<'self> { methods.map(|x| *x))) } - fn expand_struct_def(&self, cx: @ExtCtxt, - trait_span: Span, + fn expand_struct_def(&self, struct_def: &struct_def, type_ident: Ident, generics: &Generics) -> @ast::item { let methods = self.methods.map(|method_def| { let (explicit_self, self_args, nonself_args, tys) = - method_def.split_self_nonself_args(cx, trait_span, type_ident, generics); + method_def.split_self_nonself_args(self, type_ident, generics); let body = if method_def.is_static() { method_def.expand_static_struct_method_body( - cx, trait_span, + self, struct_def, type_ident, self_args, nonself_args) } else { - method_def.expand_struct_method_body(cx, trait_span, + method_def.expand_struct_method_body(self, struct_def, type_ident, self_args, nonself_args) }; - method_def.create_method(cx, trait_span, + method_def.create_method(self, type_ident, generics, explicit_self, tys, body) }); - self.create_derived_impl(cx, trait_span, type_ident, generics, methods) + self.create_derived_impl(type_ident, generics, methods) } fn expand_enum_def(&self, - cx: @ExtCtxt, trait_span: Span, enum_def: &enum_def, type_ident: Ident, generics: &Generics) -> @ast::item { let methods = self.methods.map(|method_def| { let (explicit_self, self_args, nonself_args, tys) = - method_def.split_self_nonself_args(cx, trait_span, type_ident, generics); + method_def.split_self_nonself_args(self, type_ident, generics); let body = if method_def.is_static() { method_def.expand_static_enum_method_body( - cx, trait_span, + self, enum_def, type_ident, self_args, nonself_args) } else { - method_def.expand_enum_method_body(cx, trait_span, + method_def.expand_enum_method_body(self, enum_def, type_ident, self_args, nonself_args) }; - method_def.create_method(cx, trait_span, + method_def.create_method(self, type_ident, generics, explicit_self, tys, body) }); - self.create_derived_impl(cx, trait_span, type_ident, generics, methods) + self.create_derived_impl(type_ident, generics, methods) } } impl<'self> MethodDef<'self> { fn call_substructure_method(&self, - cx: @ExtCtxt, - trait_span: Span, + trait_: &TraitDef, type_ident: Ident, self_args: &[@Expr], nonself_args: &[@Expr], @@ -474,25 +477,25 @@ impl<'self> MethodDef<'self> { -> @Expr { let substructure = Substructure { type_ident: type_ident, - method_ident: cx.ident_of(self.name), + method_ident: trait_.cx.ident_of(self.name), self_args: self_args, nonself_args: nonself_args, fields: fields }; - (self.combine_substructure)(cx, trait_span, + (self.combine_substructure)(trait_.cx, trait_.span, &substructure) } - fn get_ret_ty(&self, cx: @ExtCtxt, trait_span: Span, + fn get_ret_ty(&self, trait_: &TraitDef, generics: &Generics, type_ident: Ident) -> P<ast::Ty> { - self.ret_ty.to_ty(cx, trait_span, type_ident, generics) + self.ret_ty.to_ty(trait_.cx, trait_.span, type_ident, generics) } fn is_static(&self) -> bool { self.explicit_self.is_none() } - fn split_self_nonself_args(&self, cx: @ExtCtxt, trait_span: Span, + fn split_self_nonself_args(&self, trait_: &TraitDef, type_ident: Ident, generics: &Generics) -> (ast::explicit_self, ~[@Expr], ~[@Expr], ~[(Ident, P<ast::Ty>)]) { @@ -503,22 +506,23 @@ impl<'self> MethodDef<'self> { let ast_explicit_self = match self.explicit_self { Some(ref self_ptr) => { - let (self_expr, explicit_self) = ty::get_explicit_self(cx, trait_span, self_ptr); + let (self_expr, explicit_self) = + ty::get_explicit_self(trait_.cx, trait_.span, self_ptr); self_args.push(self_expr); nonstatic = true; explicit_self } - None => respan(trait_span, ast::sty_static), + None => codemap::respan(trait_.span, ast::sty_static), }; for (i, ty) in self.args.iter().enumerate() { - let ast_ty = ty.to_ty(cx, trait_span, type_ident, generics); - let ident = cx.ident_of(format!("__arg_{}", i)); + let ast_ty = ty.to_ty(trait_.cx, trait_.span, type_ident, generics); + let ident = trait_.cx.ident_of(format!("__arg_{}", i)); arg_tys.push((ident, ast_ty)); - let arg_expr = cx.expr_ident(trait_span, ident); + let arg_expr = trait_.cx.expr_ident(trait_.span, ident); match *ty { // for static methods, just treat any Self @@ -527,7 +531,7 @@ impl<'self> MethodDef<'self> { self_args.push(arg_expr); } Ptr(~Self, _) if nonstatic => { - self_args.push(cx.expr_deref(trait_span, arg_expr)) + self_args.push(trait_.cx.expr_deref(trait_.span, arg_expr)) } _ => { nonself_args.push(arg_expr); @@ -538,27 +542,27 @@ impl<'self> MethodDef<'self> { (ast_explicit_self, self_args, nonself_args, arg_tys) } - fn create_method(&self, cx: @ExtCtxt, trait_span: Span, + fn create_method(&self, trait_: &TraitDef, type_ident: Ident, generics: &Generics, explicit_self: ast::explicit_self, arg_types: ~[(Ident, P<ast::Ty>)], body: @Expr) -> @ast::method { // create the generics that aren't for Self - let fn_generics = self.generics.to_generics(cx, trait_span, type_ident, generics); + let fn_generics = self.generics.to_generics(trait_.cx, trait_.span, type_ident, generics); let args = arg_types.move_iter().map(|(name, ty)| { - cx.arg(trait_span, name, ty) + trait_.cx.arg(trait_.span, name, ty) }).collect(); - let ret_type = self.get_ret_ty(cx, trait_span, generics, type_ident); + let ret_type = self.get_ret_ty(trait_, generics, type_ident); - let method_ident = cx.ident_of(self.name); - let fn_decl = cx.fn_decl(args, ret_type); - let body_block = cx.block_expr(body); + let method_ident = trait_.cx.ident_of(self.name); + let fn_decl = trait_.cx.fn_decl(args, ret_type); + let body_block = trait_.cx.block_expr(body); let attrs = if self.inline { - ~[cx.attribute(trait_span, cx.meta_word(trait_span, @"inline"))] + ~[trait_.cx.attribute(trait_.span, trait_.cx.meta_word(trait_.span, @"inline"))] } else { ~[] }; @@ -573,7 +577,7 @@ impl<'self> MethodDef<'self> { decl: fn_decl, body: body_block, id: ast::DUMMY_NODE_ID, - span: trait_span, + span: trait_.span, self_id: ast::DUMMY_NODE_ID, vis: ast::inherited, } @@ -601,8 +605,7 @@ impl<'self> MethodDef<'self> { ~~~ */ fn expand_struct_method_body(&self, - cx: @ExtCtxt, - trait_span: Span, + trait_: &TraitDef, struct_def: &struct_def, type_ident: Ident, self_args: &[@Expr], @@ -613,10 +616,9 @@ impl<'self> MethodDef<'self> { // [fields of next Self arg], [etc]] let mut patterns = ~[]; for i in range(0u, self_args.len()) { - let (pat, ident_expr) = create_struct_pattern(cx, trait_span, - type_ident, struct_def, - format!("__self_{}", i), - ast::MutImmutable); + let (pat, ident_expr) = trait_.create_struct_pattern(type_ident, struct_def, + format!("__self_{}", i), + ast::MutImmutable); patterns.push(pat); raw_fields.push(ident_expr); } @@ -638,13 +640,14 @@ impl<'self> MethodDef<'self> { } }).collect() } - [] => { cx.span_bug(trait_span, "No self arguments to non-static \ - method in generic `deriving`") } + [] => { trait_.cx.span_bug(trait_.span, + "No self arguments to non-static method \ + in generic `deriving`") } }; // body of the inner most destructuring match let mut body = self.call_substructure_method( - cx, trait_span, + trait_, type_ident, self_args, nonself_args, @@ -654,23 +657,22 @@ impl<'self> MethodDef<'self> { // structs. This is actually right-to-left, but it shoudn't // matter. for (&arg_expr, &pat) in self_args.iter().zip(patterns.iter()) { - body = cx.expr_match(trait_span, arg_expr, - ~[ cx.arm(trait_span, ~[pat], body) ]) + body = trait_.cx.expr_match(trait_.span, arg_expr, + ~[ trait_.cx.arm(trait_.span, ~[pat], body) ]) } body } fn expand_static_struct_method_body(&self, - cx: @ExtCtxt, - trait_span: Span, + trait_: &TraitDef, struct_def: &struct_def, type_ident: Ident, self_args: &[@Expr], nonself_args: &[@Expr]) -> @Expr { - let summary = summarise_struct(cx, trait_span, struct_def); + let summary = trait_.summarise_struct(struct_def); - self.call_substructure_method(cx, trait_span, + self.call_substructure_method(trait_, type_ident, self_args, nonself_args, &StaticStruct(struct_def, summary)) @@ -703,15 +705,14 @@ impl<'self> MethodDef<'self> { ~~~ */ fn expand_enum_method_body(&self, - cx: @ExtCtxt, - trait_span: Span, + trait_: &TraitDef, enum_def: &enum_def, type_ident: Ident, self_args: &[@Expr], nonself_args: &[@Expr]) -> @Expr { let mut matches = ~[]; - self.build_enum_match(cx, trait_span, enum_def, type_ident, + self.build_enum_match(trait_, enum_def, type_ident, self_args, nonself_args, None, &mut matches, 0) } @@ -739,7 +740,7 @@ impl<'self> MethodDef<'self> { the first call). */ fn build_enum_match(&self, - cx: @ExtCtxt, trait_span: Span, + trait_: &TraitDef, enum_def: &enum_def, type_ident: Ident, self_args: &[@Expr], @@ -748,12 +749,13 @@ impl<'self> MethodDef<'self> { matches_so_far: &mut ~[(uint, P<ast::variant>, ~[(Span, Option<Ident>, @Expr)])], match_count: uint) -> @Expr { + let cx = trait_.cx; if match_count == self_args.len() { // we've matched against all arguments, so make the final // expression at the bottom of the match tree if matches_so_far.len() == 0 { - cx.span_bug(trait_span, "no self match on an enum in generic \ - `deriving`"); + cx.span_bug(trait_.span, + "no self match on an enum in generic `deriving`"); } // we currently have a vec of vecs, where each // subvec is the fields of one of the arguments, @@ -803,7 +805,7 @@ impl<'self> MethodDef<'self> { substructure = EnumNonMatching(*matches_so_far); } } - self.call_substructure_method(cx, trait_span, type_ident, + self.call_substructure_method(trait_, type_ident, self_args, nonself_args, &substructure) @@ -822,20 +824,19 @@ impl<'self> MethodDef<'self> { // make a matching-variant match, and a _ match. let index = match matching { Some(i) => i, - None => cx.span_bug(trait_span, + None => cx.span_bug(trait_.span, "Non-matching variants when required to \ be matching in generic `deriving`") }; // matching-variant match let variant = enum_def.variants[index]; - let (pattern, idents) = create_enum_variant_pattern(cx, - variant, - current_match_str, - ast::MutImmutable); + let (pattern, idents) = trait_.create_enum_variant_pattern(variant, + current_match_str, + ast::MutImmutable); matches_so_far.push((index, variant, idents)); - let arm_expr = self.build_enum_match(cx, trait_span, + let arm_expr = self.build_enum_match(trait_, enum_def, type_ident, self_args, nonself_args, @@ -843,25 +844,24 @@ impl<'self> MethodDef<'self> { matches_so_far, match_count + 1); matches_so_far.pop(); - arms.push(cx.arm(trait_span, ~[ pattern ], arm_expr)); + arms.push(cx.arm(trait_.span, ~[ pattern ], arm_expr)); if enum_def.variants.len() > 1 { let e = &EnumNonMatching(&[]); - let wild_expr = self.call_substructure_method(cx, trait_span, type_ident, + let wild_expr = self.call_substructure_method(trait_, type_ident, self_args, nonself_args, e); - let wild_arm = cx.arm(trait_span, - ~[ cx.pat_wild(trait_span) ], + let wild_arm = cx.arm(trait_.span, + ~[ cx.pat_wild(trait_.span) ], wild_expr); arms.push(wild_arm); } } else { // create an arm matching on each variant for (index, &variant) in enum_def.variants.iter().enumerate() { - let (pattern, idents) = create_enum_variant_pattern(cx, - variant, - current_match_str, - ast::MutImmutable); + let (pattern, idents) = trait_.create_enum_variant_pattern(variant, + current_match_str, + ast::MutImmutable); matches_so_far.push((index, variant, idents)); let new_matching = @@ -870,7 +870,7 @@ impl<'self> MethodDef<'self> { Some(i) if index == i => Some(i), _ => None }; - let arm_expr = self.build_enum_match(cx, trait_span, + let arm_expr = self.build_enum_match(trait_, enum_def, type_ident, self_args, nonself_args, @@ -879,19 +879,18 @@ impl<'self> MethodDef<'self> { match_count + 1); matches_so_far.pop(); - let arm = cx.arm(trait_span, ~[ pattern ], arm_expr); + let arm = cx.arm(trait_.span, ~[ pattern ], arm_expr); arms.push(arm); } } // match foo { arm, arm, arm, ... } - cx.expr_match(trait_span, self_args[match_count], arms) + cx.expr_match(trait_.span, self_args[match_count], arms) } } fn expand_static_enum_method_body(&self, - cx: @ExtCtxt, - trait_span: Span, + trait_: &TraitDef, enum_def: &enum_def, type_ident: Ident, self_args: &[@Expr], @@ -902,158 +901,156 @@ impl<'self> MethodDef<'self> { let summary = match v.node.kind { ast::tuple_variant_kind(ref args) => Unnamed(args.map(|va| va.ty.span)), ast::struct_variant_kind(struct_def) => { - summarise_struct(cx, trait_span, struct_def) + trait_.summarise_struct(struct_def) } }; (ident, summary) }); - self.call_substructure_method(cx, - trait_span, type_ident, + self.call_substructure_method(trait_, type_ident, self_args, nonself_args, &StaticEnum(enum_def, summary)) } } -fn summarise_struct(cx: @ExtCtxt, trait_span: Span, - struct_def: &struct_def) -> StaticFields { - let mut named_idents = ~[]; - let mut just_spans = ~[]; - for field in struct_def.fields.iter() { - match field.node.kind { - ast::named_field(ident, _) => named_idents.push((ident, field.span)), - ast::unnamed_field => just_spans.push(field.span), +#[deriving(Eq)] // dogfooding! +enum StructType { + Unknown, Record, Tuple +} + +// general helper methods. +impl<'a> TraitDef<'a> { + fn summarise_struct(&self, struct_def: &struct_def) -> StaticFields { + let mut named_idents = ~[]; + let mut just_spans = ~[]; + for field in struct_def.fields.iter(){ + let sp = field.span; + match field.node.kind { + ast::named_field(ident, _) => named_idents.push((ident, sp)), + ast::unnamed_field => just_spans.push(sp), + } } - } - match (just_spans.is_empty(), named_idents.is_empty()) { - (false, false) => cx.span_bug(trait_span, - "A struct with named and unnamed \ - fields in generic `deriving`"), - // named fields - (_, false) => Named(named_idents), - // tuple structs (includes empty structs) - (_, _) => Unnamed(just_spans) + match (just_spans.is_empty(), named_idents.is_empty()) { + (false, false) => self.cx.span_bug(self.span, + "A struct with named and unnamed \ + fields in generic `deriving`"), + // named fields + (_, false) => Named(named_idents), + // tuple structs (includes empty structs) + (_, _) => Unnamed(just_spans) + } } -} -pub fn create_subpatterns(cx: @ExtCtxt, + fn create_subpatterns(&self, field_paths: ~[ast::Path], mutbl: ast::Mutability) - -> ~[@ast::Pat] { - field_paths.map(|path| { - cx.pat(path.span, - ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None)) - }) -} + -> ~[@ast::Pat] { + field_paths.map(|path| { + self.cx.pat(path.span, + ast::PatIdent(ast::BindByRef(mutbl), (*path).clone(), None)) + }) + } -#[deriving(Eq)] // dogfooding! -enum StructType { - Unknown, Record, Tuple -} + fn create_struct_pattern(&self, + struct_ident: Ident, + struct_def: &struct_def, + prefix: &str, + mutbl: ast::Mutability) + -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) { + let cx = self.cx; + + if struct_def.fields.is_empty() { + return ( + cx.pat_ident_binding_mode( + self.span, struct_ident, ast::BindByValue(ast::MutImmutable)), + ~[]); + } -fn create_struct_pattern(cx: @ExtCtxt, - trait_span: Span, - struct_ident: Ident, - struct_def: &struct_def, - prefix: &str, - mutbl: ast::Mutability) - -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) { - if struct_def.fields.is_empty() { - return ( - cx.pat_ident_binding_mode( - trait_span, struct_ident, ast::BindByValue(ast::MutImmutable)), - ~[]); - } + let matching_path = cx.path(self.span, ~[ struct_ident ]); - let matching_path = cx.path(trait_span, ~[ struct_ident ]); + let mut paths = ~[]; + let mut ident_expr = ~[]; + let mut struct_type = Unknown; - let mut paths = ~[]; - let mut ident_expr = ~[]; - let mut struct_type = Unknown; + for (i, struct_field) in struct_def.fields.iter().enumerate() { + let sp = struct_field.span; + let opt_id = match struct_field.node.kind { + ast::named_field(ident, _) if (struct_type == Unknown || + struct_type == Record) => { + struct_type = Record; + Some(ident) + } + ast::unnamed_field if (struct_type == Unknown || + struct_type == Tuple) => { + struct_type = Tuple; + None + } + _ => { + cx.span_bug(sp, "A struct with named and unnamed fields in `deriving`"); + } + }; + let path = cx.path_ident(sp, cx.ident_of(format!("{}_{}", prefix, i))); + paths.push(path.clone()); + ident_expr.push((sp, opt_id, cx.expr_path(path))); + } - for (i, struct_field) in struct_def.fields.iter().enumerate() { - let opt_id = match struct_field.node.kind { - ast::named_field(ident, _) if (struct_type == Unknown || - struct_type == Record) => { - struct_type = Record; - Some(ident) - } - ast::unnamed_field if (struct_type == Unknown || - struct_type == Tuple) => { - struct_type = Tuple; - None - } - _ => { - cx.span_bug(struct_field.span, - "A struct with named and unnamed fields in `deriving`"); - } + let subpats = self.create_subpatterns(paths, mutbl); + + // 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.iter().zip(ident_expr.iter()).map(|(&pat, &(_, id, _))| { + // id is guaranteed to be Some + ast::FieldPat { ident: id.unwrap(), pat: pat } + }).collect(); + cx.pat_struct(self.span, matching_path, field_pats) + } else { + cx.pat_enum(self.span, matching_path, subpats) }; - let path = cx.path_ident(struct_field.span, - cx.ident_of(format!("{}_{}", prefix, i))); - paths.push(path.clone()); - ident_expr.push((struct_field.span, opt_id, cx.expr_path(path))); - } - let subpats = create_subpatterns(cx, paths, mutbl); + (pattern, ident_expr) + } - // 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.iter().zip(ident_expr.iter()).map(|(&pat, &(_, id, _))| { - // id is guaranteed to be Some - ast::FieldPat { ident: id.unwrap(), pat: pat } - }).collect(); - cx.pat_struct(trait_span, matching_path, field_pats) - } else { - cx.pat_enum(trait_span, matching_path, subpats) - }; + fn create_enum_variant_pattern(&self, + variant: &ast::variant, + prefix: &str, + mutbl: ast::Mutability) + -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) { + let cx = self.cx; + let variant_ident = variant.node.name; + match variant.node.kind { + ast::tuple_variant_kind(ref variant_args) => { + if variant_args.is_empty() { + return (cx.pat_ident_binding_mode(variant.span, variant_ident, + ast::BindByValue(ast::MutImmutable)), + ~[]); + } - (pattern, ident_expr) -} + let matching_path = cx.path_ident(variant.span, variant_ident); -fn create_enum_variant_pattern(cx: @ExtCtxt, - variant: &ast::variant, - prefix: &str, - mutbl: ast::Mutability) - -> (@ast::Pat, ~[(Span, Option<Ident>, @Expr)]) { - - let variant_ident = variant.node.name; - match variant.node.kind { - ast::tuple_variant_kind(ref variant_args) => { - if variant_args.is_empty() { - return (cx.pat_ident_binding_mode(variant.span, variant_ident, - ast::BindByValue(ast::MutImmutable)), - ~[]); - } + let mut paths = ~[]; + let mut ident_expr = ~[]; + for (i, va) in variant_args.iter().enumerate() { + let sp = va.ty.span; + let path = cx.path_ident(sp, cx.ident_of(format!("{}_{}", prefix, i))); - let matching_path = cx.path_ident(variant.span, variant_ident); + paths.push(path.clone()); + ident_expr.push((sp, None, cx.expr_path(path))); + } - let mut paths = ~[]; - let mut ident_expr = ~[]; - for (i, va) in variant_args.iter().enumerate() { - let path = cx.path_ident(va.ty.span, - cx.ident_of(format!("{}_{}", prefix, i))); + let subpats = self.create_subpatterns(paths, mutbl); - paths.push(path.clone()); - ident_expr.push((va.ty.span, None, cx.expr_path(path))); + (cx.pat_enum(variant.span, matching_path, subpats), + ident_expr) + } + ast::struct_variant_kind(struct_def) => { + self.create_struct_pattern(variant_ident, struct_def, + prefix, mutbl) } - - let subpats = create_subpatterns(cx, paths, mutbl); - - (cx.pat_enum(variant.span, matching_path, subpats), - ident_expr) - } - ast::struct_variant_kind(struct_def) => { - create_struct_pattern(cx, variant.span, - variant_ident, struct_def, - prefix, - mutbl) } } } - - /* helpful premade recipes */ /** diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index f291d2b751d..837b8bd59ec 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -20,6 +20,8 @@ pub fn expand_deriving_iter_bytes(cx: @ExtCtxt, mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "to_bytes", "IterBytes"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -40,7 +42,7 @@ pub fn expand_deriving_iter_bytes(cx: @ExtCtxt, ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } fn iter_bytes_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr { diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index b26a3a09f04..73ea627ff54 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -20,6 +20,8 @@ pub fn expand_deriving_from_primitive(cx: @ExtCtxt, mitem: @MetaItem, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "num", "FromPrimitive"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -59,7 +61,7 @@ pub fn expand_deriving_from_primitive(cx: @ExtCtxt, ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } fn cs_from(name: &str, cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr { diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index 40fdee481ed..91ed60324cf 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -22,6 +22,8 @@ pub fn expand_deriving_rand(cx: @ExtCtxt, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "rand", "Rand"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -45,7 +47,7 @@ pub fn expand_deriving_rand(cx: @ExtCtxt, } ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } fn rand_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr { diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs index 193dc4965fc..fd8c21f4f98 100644 --- a/src/libsyntax/ext/deriving/to_str.rs +++ b/src/libsyntax/ext/deriving/to_str.rs @@ -21,6 +21,8 @@ pub fn expand_deriving_to_str(cx: @ExtCtxt, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "to_str", "ToStr"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -37,7 +39,7 @@ pub fn expand_deriving_to_str(cx: @ExtCtxt, } ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } // It used to be the case that this deriving implementation invoked diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs index 1fdb4131689..67f14a8d486 100644 --- a/src/libsyntax/ext/deriving/zero.rs +++ b/src/libsyntax/ext/deriving/zero.rs @@ -20,6 +20,8 @@ pub fn expand_deriving_zero(cx: @ExtCtxt, in_items: ~[@item]) -> ~[@item] { let trait_def = TraitDef { + cx: cx, span: span, + path: Path::new(~["std", "num", "Zero"]), additional_bounds: ~[], generics: LifetimeBounds::empty(), @@ -52,7 +54,7 @@ pub fn expand_deriving_zero(cx: @ExtCtxt, } ] }; - trait_def.expand(cx, span, mitem, in_items) + trait_def.expand(mitem, in_items) } fn zero_substructure(cx: @ExtCtxt, span: Span, substr: &Substructure) -> @Expr { |
