diff options
| author | Lindsey Kuper <lindsey@rockstargirl.org> | 2012-07-10 13:44:20 -0700 |
|---|---|---|
| committer | Lindsey Kuper <lindsey@rockstargirl.org> | 2012-07-13 11:16:07 -0700 |
| commit | fc9c4c32451dadab4f8a81897e8fc83ae6473d95 (patch) | |
| tree | d54e7d2d8ecce561fb04375e31516ccaf1521aa0 /src/libsyntax | |
| parent | d5563d732dfb4ebbf50ad221d8d4568319210a65 (diff) | |
| download | rust-fc9c4c32451dadab4f8a81897e8fc83ae6473d95.tar.gz rust-fc9c4c32451dadab4f8a81897e8fc83ae6473d95.zip | |
Front-end support for default impls in traits.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 56 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 24 |
5 files changed, 88 insertions, 16 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e79e5e2ab77..f79f6cbcae2 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -453,6 +453,15 @@ type ty_method = {ident: ident, attrs: ~[attribute], decl: fn_decl, tps: ~[ty_param], span: span}; #[auto_serialize] +// A trait method is either required (meaning it doesn't have an +// implementation, just a signature) or provided (meaning it has a default +// implementation). +enum trait_method { + required(ty_method), + provided(@method), +} + +#[auto_serialize] enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } #[auto_serialize] @@ -695,7 +704,7 @@ enum item_ { /* dtor is optional */ option<class_dtor> ), - item_trait(~[ty_param], ~[ty_method]), + item_trait(~[ty_param], ~[trait_method]), item_impl(~[ty_param], option<@trait_ref> /* trait */, @ty /* self */, ~[@method]), item_mac(mac), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 1e2de4f5bfa..5675ecadf62 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -511,6 +511,9 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { visit_ty_method: fn@(_ty_m: ty_method) { }, + visit_trait_method: fn@(_ty_m: trait_method) { + }, + visit_class_item: fn@(c: @class_member) { alt c.node { instance_var(_, _, _, id,_) { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e1f3eb3217c..5a1eb7636ba 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -42,14 +42,14 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, mtc_rep, mtc_tok, mul, mutability, neg, noreturn, not, pat, pat_box, pat_enum, pat_ident, pat_lit, pat_range, pat_rec, pat_tup, pat_uniq, pat_wild, path, private, proto, proto_any, - proto_bare, proto_block, proto_box, proto_uniq, public, pure_fn, - purity, re_anon, re_named, region, rem, ret_style, - return_val, shl, shr, stmt, stmt_decl, - stmt_expr, stmt_semi, subtract, token_tree, trait_ref, tt_delim, - tt_dotdotdot, tt_flat, tt_interpolate, ty, ty_, ty_bot, ty_box, - ty_constr, ty_constr_, ty_constr_arg, ty_field, ty_fn, ty_infer, - ty_mac, ty_method, ty_nil, ty_param, ty_path, ty_ptr, ty_rec, - ty_rptr, ty_tup, ty_u32, ty_uniq, ty_vec, ty_vstore, + proto_bare, proto_block, proto_box, proto_uniq, provided, public, + pure_fn, purity, re_anon, re_named, region, rem, required, + ret_style, return_val, shl, shr, stmt, stmt_decl, stmt_expr, + stmt_semi, subtract, token_tree, trait_method, trait_ref, + tt_delim, tt_dotdotdot, tt_flat, tt_interpolate, ty, ty_, ty_bot, + ty_box, ty_constr, ty_constr_, ty_constr_arg, ty_field, ty_fn, + ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_path, ty_ptr, + ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq, ty_vec, ty_vstore, unchecked_blk, uniq, unsafe_blk, unsafe_fn, variant, view_item, view_item_, view_item_export, view_item_import, view_item_use, view_path, view_path_glob, view_path_list, view_path_simple, @@ -275,7 +275,7 @@ class parser { constraints: constrs}; } - fn parse_ty_methods() -> ~[ty_method] { + fn parse_trait_methods() -> ~[trait_method] { do self.parse_unspanned_seq(token::LBRACE, token::RBRACE, seq_sep_none()) |p| { let attrs = p.parse_outer_attributes(); @@ -284,12 +284,42 @@ class parser { let ident = p.parse_method_name(); let tps = p.parse_ty_params(); let d = p.parse_ty_fn_decl(pur), fhi = p.last_span.hi; - self.expect(token::SEMI); - {ident: ident, attrs: attrs, decl: {purity: pur with d}, tps: tps, - span: mk_sp(flo, fhi)} + #debug["parse_trait_methods(): trait method ends in %s", + token_to_str(self.reader, self.token)]; + alt self.token { + token::SEMI { + self.bump(); + required({ident: ident, attrs: attrs, + decl: {purity: pur with d}, tps: tps, + span: mk_sp(flo, fhi)}) + } + token::LBRACE { + self.bump(); + let (inner_attrs, body) = + self.parse_inner_attrs_and_block(true); + let attrs = vec::append(attrs, inner_attrs); + self.eat(token::RBRACE); + provided(@{ident: ident, + attrs: attrs, + tps: tps, + decl: d, + body: body, + id: self.get_id(), + span: mk_sp(flo, fhi), + self_id: self.get_id(), + // Provided traits methods always public for now + vis: public}) + } + + _ { self.fatal("expected ';' or '}` \ + but found `" + + token_to_str(self.reader, self.token) + "`"); + } + } } } + fn parse_mt() -> mt { let mutbl = self.parse_mutability(); let t = self.parse_ty(false); @@ -2127,7 +2157,7 @@ class parser { let ident = self.parse_ident(); self.parse_region_param(); let tps = self.parse_ty_params(); - let meths = self.parse_ty_methods(); + let meths = self.parse_trait_methods(); (ident, item_trait(tps, meths), none) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d43ed8043ee..c802e40dd05 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -5,6 +5,7 @@ import pp::{break_offset, word, printer, space, zerobreak, hardbreak, breaks, consistent, inconsistent, eof}; import diagnostic; +import ast::{required, provided}; import ast_util::operator_prec; import dvec::{dvec, extensions}; import parse::classify::*; @@ -593,7 +594,7 @@ fn print_item(s: ps, &&item: @ast::item) { print_type_params(s, tps); word(s.s, " "); bopen(s); - for methods.each |meth| { print_ty_method(s, meth); } + for methods.each |meth| { print_trait_method(s, meth); } bclose(s, item.span); } ast::item_mac({node: ast::mac_invoc_tt(pth, tts), _}) { @@ -647,6 +648,13 @@ fn print_ty_method(s: ps, m: ast::ty_method) { word(s.s, ";"); } +fn print_trait_method(s: ps, m: ast::trait_method) { + alt m { + required(ty_m) { print_ty_method(s, ty_m) } + provided(m) { print_method(s, m) } + } +} + fn print_method(s: ps, meth: @ast::method) { hardbreak_if_not_bol(s); maybe_print_comment(s, meth.span.lo); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 5dc42fd4823..be9f76650da 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -62,6 +62,7 @@ type visitor<E> = visit_constr: fn@(@path, span, node_id, E, vt<E>), visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>), visit_ty_method: fn@(ty_method, E, vt<E>), + visit_trait_method: fn@(trait_method, E, vt<E>), visit_class_item: fn@(@class_member, E, vt<E>)}; fn default_visitor<E>() -> visitor<E> { @@ -81,6 +82,7 @@ fn default_visitor<E>() -> visitor<E> { visit_constr: |a,b,c,d,e|visit_constr::<E>(a, b, c, d, e), visit_fn: |a,b,c,d,e,f,g|visit_fn::<E>(a, b, c, d, e, f, g), visit_ty_method: |a,b,c|visit_ty_method::<E>(a, b, c), + visit_trait_method: |a,b,c|visit_trait_method::<E>(a, b, c), visit_class_item: |a,b,c|visit_class_item::<E>(a, b, c)}; } @@ -160,7 +162,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { item_trait(tps, methods) { v.visit_ty_params(tps, e, v); for methods.each |m| { - v.visit_ty_method(m, e, v); + v.visit_trait_method(m, e, v); } } item_mac(m) { visit_mac(m, e, v) } @@ -317,6 +319,17 @@ fn visit_ty_method<E>(m: ty_method, e: E, v: vt<E>) { v.visit_ty(m.decl.output, e, v); } +fn visit_trait_method<E>(m: trait_method, e: E, v: vt<E>) { + alt m { + required(ty_m) { + v.visit_ty_method(ty_m, e, v) + } + provided(m) { + visit_method_helper(m, e, v) + } + } +} + fn visit_block<E>(b: ast::blk, e: E, v: vt<E>) { for b.node.view_items.each |vi| { v.visit_view_item(vi, e, v); } for b.node.stmts.each |s| { v.visit_stmt(s, e, v); } @@ -465,6 +478,7 @@ type simple_visitor = visit_constr: fn@(@path, span, node_id), visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id), visit_ty_method: fn@(ty_method), + visit_trait_method: fn@(trait_method), visit_class_item: fn@(@class_member)}; fn simple_ignore_ty(_t: @ty) {} @@ -487,6 +501,7 @@ fn default_simple_visitor() -> simple_visitor { visit_fn: fn@(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span, _id: node_id) { }, visit_ty_method: fn@(_m: ty_method) { }, + visit_trait_method: fn@(_m: trait_method) { }, visit_class_item: fn@(_c: @class_member) {} }; } @@ -546,6 +561,11 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { f(ty); visit_ty_method(ty, e, v); } + fn v_trait_method(f: fn@(trait_method), m: trait_method, &&e: (), + v: vt<()>) { + f(m); + visit_trait_method(m, e, v); + } fn v_ty_params(f: fn@(~[ty_param]), ps: ~[ty_param], &&e: (), v: vt<()>) { @@ -596,6 +616,8 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> { v_fn(v.visit_fn, a, b, c, d, e, f, g), visit_ty_method: |a,b,c| v_ty_method(v.visit_ty_method, a, b, c), + visit_trait_method: |a,b,c| + v_trait_method(v.visit_trait_method, a, b, c), visit_class_item: |a,b,c| v_class_item(v.visit_class_item, a, b, c) }); |
