Skip to content

Commit 9d23029

Browse files
committed
libsyntax: Implement deriving for struct-like enum variants. r=brson
1 parent efb9b74 commit 9d23029

File tree

3 files changed

+68
-16
lines changed

3 files changed

+68
-16
lines changed

src/libsyntax/ext/build.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ fn mk_pat_enum(cx: ext_ctxt,
219219
let pat = ast::pat_enum(path, Some(move subpats));
220220
mk_pat(cx, span, move pat)
221221
}
222+
fn mk_pat_struct(cx: ext_ctxt,
223+
span: span,
224+
path: @ast::path,
225+
+field_pats: ~[ast::field_pat])
226+
-> @ast::pat {
227+
let pat = ast::pat_struct(path, move field_pats, false);
228+
mk_pat(cx, span, move pat)
229+
}
222230
fn mk_bool(cx: ext_ctxt, span: span, value: bool) -> @ast::expr {
223231
let lit_expr = ast::expr_lit(@{ node: ast::lit_bool(value), span: span });
224232
build::mk_expr(cx, span, move lit_expr)

src/libsyntax/ext/deriving.rs

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,26 @@ fn create_iter_bytes_method(cx: ext_ctxt,
318318
}
319319
}
320320

321+
fn create_subpatterns(cx: ext_ctxt,
322+
span: span,
323+
prefix: ~str,
324+
n: uint)
325+
-> ~[@pat] {
326+
let subpats = dvec::DVec();
327+
for uint::range(0, n) |_i| {
328+
// Create the subidentifier.
329+
let index = subpats.len().to_str();
330+
let ident = cx.ident_of(prefix + index);
331+
332+
// Create the subpattern.
333+
let subpath = build::mk_raw_path(span, ~[ ident ]);
334+
let subpat = pat_ident(bind_by_ref(m_imm), subpath, None);
335+
let subpat = build::mk_pat(cx, span, move subpat);
336+
subpats.push(subpat);
337+
}
338+
return dvec::unwrap(move subpats);
339+
}
340+
321341
fn create_enum_variant_pattern(cx: ext_ctxt,
322342
span: span,
323343
variant: &variant,
@@ -330,25 +350,37 @@ fn create_enum_variant_pattern(cx: ext_ctxt,
330350
return build::mk_pat_ident(cx, span, variant_ident);
331351
}
332352

333-
let subpats = dvec::DVec();
334-
for variant_args.each |_variant_arg| {
335-
// Create the subidentifier.
336-
let index = subpats.len().to_str();
337-
let ident = cx.ident_of(prefix + index);
338-
339-
// Create the subpattern.
340-
let subpath = build::mk_raw_path(span, ~[ ident ]);
341-
let subpat = pat_ident(bind_by_ref(m_imm), subpath, None);
342-
let subpat = build::mk_pat(cx, span, move subpat);
343-
subpats.push(subpat);
344-
}
345-
346353
let matching_path = build::mk_raw_path(span, ~[ variant_ident ]);
347-
let subpats = dvec::unwrap(move subpats);
354+
let subpats = create_subpatterns(cx,
355+
span,
356+
prefix,
357+
variant_args.len());
358+
348359
return build::mk_pat_enum(cx, span, matching_path, move subpats);
349360
}
350-
struct_variant_kind(*) => {
351-
cx.span_unimpl(span, ~"struct variants for `deriving`");
361+
struct_variant_kind(struct_def) => {
362+
let matching_path = build::mk_raw_path(span, ~[ variant_ident ]);
363+
let subpats = create_subpatterns(cx,
364+
span,
365+
prefix,
366+
struct_def.fields.len());
367+
368+
let field_pats = dvec::DVec();
369+
for struct_def.fields.eachi |i, struct_field| {
370+
let ident = match struct_field.node.kind {
371+
named_field(ident, _, _) => ident,
372+
unnamed_field => {
373+
cx.span_bug(span, ~"unexpected unnamed field");
374+
}
375+
};
376+
field_pats.push({ ident: ident, pat: subpats[i] });
377+
}
378+
let field_pats = dvec::unwrap(move field_pats);
379+
380+
return build::mk_pat_struct(cx,
381+
span,
382+
matching_path,
383+
move field_pats);
352384
}
353385
enum_variant_kind(*) => {
354386
cx.span_unimpl(span, ~"enum variants for `deriving`");
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#[deriving_eq]
2+
enum S {
3+
X { x: int, y: int },
4+
Y
5+
}
6+
7+
fn main() {
8+
let x = X { x: 1, y: 2 };
9+
assert x == x;
10+
assert !(x != x);
11+
}
12+

0 commit comments

Comments
 (0)