Skip to content

Commit 3698ea7

Browse files
committed
libsyntax: abstract most of the deriving boilerplate into a simpler(r) interface.
Pulls out many of the common patterns from the Eq and Clone deriving code (and invents a few of its own), so that deriving instances are very easy to write for a certain class of traits. (Basically, those which don't have parameters and where all methods only take arguments of type `&Self` and return either `Self` or types with no parameters.)
1 parent cf34b31 commit 3698ea7

File tree

7 files changed

+915
-42
lines changed

7 files changed

+915
-42
lines changed

src/libsyntax/ext/deriving/clone.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ fn create_derived_clone_impl(cx: @ext_ctxt,
5555
cx.ident_of(~"Clone"),
5656
];
5757
let trait_path = build::mk_raw_path_global(span, trait_path);
58-
create_derived_impl(cx, span, type_ident, generics, methods, trait_path, opt_vec::Empty)
58+
create_derived_impl(cx, span, type_ident, generics, methods, trait_path,
59+
opt_vec::Empty, opt_vec::Empty)
5960
}
6061
// Creates a method from the given expression conforming to the signature of
6162
// the `clone` method.
@@ -219,7 +220,7 @@ fn expand_deriving_clone_tuple_struct_method(cx: @ext_ctxt,
219220
let mut subcalls = ~[];
220221
for uint::range(0, struct_def.fields.len()) |i| {
221222
// Create the expression for this field.
222-
let field_ident = cx.ident_of(~"__self" + i.to_str());
223+
let field_ident = cx.ident_of(~"__self_" + i.to_str());
223224
let field = build::mk_path(cx, span, ~[ field_ident ]);
224225

225226
// Call the substructure method.
@@ -262,7 +263,7 @@ fn expand_deriving_clone_enum_method(cx: @ext_ctxt,
262263
let mut subcalls = ~[];
263264
for uint::range(0, variant_arg_count(cx, span, variant)) |j| {
264265
// Create the expression for this field.
265-
let field_ident = cx.ident_of(~"__self" + j.to_str());
266+
let field_ident = cx.ident_of(~"__self_" + j.to_str());
266267
let field = build::mk_path(cx, span, ~[ field_ident ]);
267268

268269
// Call the substructure method.

src/libsyntax/ext/deriving/decodable.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ fn create_derived_decodable_impl(
8181
generics,
8282
methods,
8383
trait_path,
84-
generic_ty_params
84+
generic_ty_params,
85+
opt_vec::Empty
8586
)
8687
}
8788

src/libsyntax/ext/deriving/encodable.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ fn create_derived_encodable_impl(
8181
generics,
8282
methods,
8383
trait_path,
84-
generic_ty_params
84+
generic_ty_params,
85+
opt_vec::Empty
8586
)
8687
}
8788

@@ -306,7 +307,7 @@ fn expand_deriving_encodable_enum_method(
306307
let variant_arg_len = variant_arg_count(cx, span, variant);
307308
for uint::range(0, variant_arg_len) |j| {
308309
// Create the expression for this field.
309-
let field_ident = cx.ident_of(~"__self" + j.to_str());
310+
let field_ident = cx.ident_of(~"__self_" + j.to_str());
310311
let field = build::mk_path(cx, span, ~[ field_ident ]);
311312

312313
// Call the substructure method.

src/libsyntax/ext/deriving/eq.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ fn create_derived_eq_impl(cx: @ext_ctxt,
131131
cx.ident_of(~"Eq")
132132
];
133133
let trait_path = build::mk_raw_path_global(span, trait_path);
134-
create_derived_impl(cx, span, type_ident, generics, methods, trait_path, opt_vec::Empty)
134+
create_derived_impl(cx, span, type_ident, generics, methods, trait_path, opt_vec::Empty, [])
135135
}
136136

137137
fn call_substructure_eq_method(cx: @ext_ctxt,
@@ -338,13 +338,13 @@ fn expand_deriving_eq_enum_method(cx: @ext_ctxt,
338338
let mut matching_body_expr = None;
339339
for uint::range(0, variant_arg_count(cx, span, self_variant)) |i| {
340340
// Create the expression for the other field.
341-
let other_field_ident = cx.ident_of(~"__other" + i.to_str());
341+
let other_field_ident = cx.ident_of(~"__other_" + i.to_str());
342342
let other_field = build::mk_path(cx,
343343
span,
344344
~[ other_field_ident ]);
345345

346346
// Create the expression for this field.
347-
let self_field_ident = cx.ident_of(~"__self" + i.to_str());
347+
let self_field_ident = cx.ident_of(~"__self_" + i.to_str());
348348
let self_field = build::mk_path(cx, span, ~[ self_field_ident ]);
349349

350350
// Call the substructure method.
@@ -456,10 +456,10 @@ fn expand_deriving_eq_struct_tuple_method(cx: @ext_ctxt,
456456
// Create comparison expression, comparing each of the fields
457457
let mut match_body = None;
458458
for fields.eachi |i, _| {
459-
let other_field_ident = cx.ident_of(other_str + i.to_str());
459+
let other_field_ident = cx.ident_of(fmt!("%s_%u", other_str, i));
460460
let other_field = build::mk_path(cx, span, ~[ other_field_ident ]);
461461

462-
let self_field_ident = cx.ident_of(self_str + i.to_str());
462+
let self_field_ident = cx.ident_of(fmt!("%s_%u", self_str, i));
463463
let self_field = build::mk_path(cx, span, ~[ self_field_ident ]);
464464

465465
call_substructure_eq_method(cx, span, self_field, other_field,

0 commit comments

Comments
 (0)