diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-07-18 09:31:53 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-07-18 16:05:17 -0700 |
| commit | 3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac (patch) | |
| tree | 0613184ab1f468f2a1b776c1d4c6df4ac15d69db /src/libsyntax | |
| parent | 1528256fdc26199dd58b390e42e2d0dc53b9703d (diff) | |
| download | rust-3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac.tar.gz rust-3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac.zip | |
syntax: Parse multiple trait refs in a single implementation
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/pipec.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 29 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 6 |
5 files changed, 34 insertions, 18 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 65ff9245fd1..79523acb99b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -635,8 +635,10 @@ enum item_ { option<class_dtor> ), item_trait(~[ty_param], ~[trait_method]), - item_impl(~[ty_param], option<@trait_ref> /* trait */, - @ty /* self */, ~[@method]), + item_impl(~[ty_param], + ~[@trait_ref], /* traits this impl implements */ + @ty, /* self */ + ~[@method]), item_mac(mac), } diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index c6b1a2d6932..df5df748a74 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -21,6 +21,7 @@ import ast_builder::append_types; import ast_builder::ast_builder; import ast_builder::methods; import ast_builder::path; +import ast_builder::path_concat; trait gen_send { fn gen_send(cx: ext_ctxt) -> @ast::item; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8336d6b39ab..6bcf22c8220 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2085,13 +2085,22 @@ class parser { (some(id), self.parse_ty_params()) } }; - let ifce = if self.eat_keyword(~"of") { - let path = self.parse_path_with_tps(false); - if option::is_none(ident) { - ident = some(vec::last(path.idents)); + let traits; + if self.eat_keyword(~"of") { + let for_atom = interner::intern(*self.reader.interner(), @~"for"); + traits = self.parse_trait_ref_list(token::IDENT(for_atom, false)); + if traits.len() >= 1 && option::is_none(ident) { + ident = some(vec::last(traits[0].path.idents)); } - some(@{path: path, ref_id: self.get_id(), impl_id: self.get_id()}) - } else { none }; + if traits.len() == 0 { + self.fatal(~"BUG: 'of' but no trait"); + } + if traits.len() > 1 { + self.fatal(~"BUG: multiple traits"); + } + } else { + traits = ~[]; + }; let ident = alt ident { some(name) { name } none { self.expect_keyword(~"of"); fail; } @@ -2103,7 +2112,7 @@ class parser { while !self.eat(token::RBRACE) { vec::push(meths, self.parse_method(public)); } - (ident, item_impl(tps, ifce, ty, meths), none) + (ident, item_impl(tps, traits, ty, meths), none) } // Instantiates ident <i> with references to <typarams> as arguments. @@ -2127,9 +2136,9 @@ class parser { ref_id: self.get_id(), impl_id: self.get_id()} } - fn parse_trait_ref_list() -> ~[@trait_ref] { + fn parse_trait_ref_list(ket: token::token) -> ~[@trait_ref] { self.parse_seq_to_before_end( - token::LBRACE, seq_sep_trailing_disallowed(token::COMMA), + ket, seq_sep_trailing_disallowed(token::COMMA), |p| p.parse_trait_ref()) } @@ -2139,7 +2148,7 @@ class parser { let ty_params = self.parse_ty_params(); let class_path = self.ident_to_path_tys(class_name, ty_params); let traits : ~[@trait_ref] = if self.eat(token::COLON) - { self.parse_trait_ref_list() } + { self.parse_trait_ref_list(token::LBRACE) } else { ~[] }; self.expect(token::LBRACE); let mut ms: ~[@class_member] = ~[]; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 2d087d8d9df..b1730bfc587 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -558,16 +558,18 @@ fn print_item(s: ps, &&item: @ast::item) { } bclose(s, item.span); } - ast::item_impl(tps, ifce, ty, methods) { + ast::item_impl(tps, traits, ty, methods) { head(s, ~"impl"); word(s.s, *item.ident); print_type_params(s, tps); space(s.s); - option::iter(ifce, |p| { + if vec::len(traits) != 0u { word_nbsp(s, ~"of"); - print_path(s, p.path, false); + do commasep(s, inconsistent, traits) |s, p| { + print_path(s, p.path, false); + } space(s.s); - }); + } word_nbsp(s, ~"for"); print_type(s, ty); space(s.s); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index ead8e981d7a..14fe18edd09 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -135,9 +135,11 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { for vr.node.args.each |va| { v.visit_ty(va.ty, e, v); } } } - item_impl(tps, ifce, ty, methods) { + item_impl(tps, traits, ty, methods) { v.visit_ty_params(tps, e, v); - option::iter(ifce, |p| visit_path(p.path, e, v)); + for traits.each |p| { + visit_path(p.path, e, v); + } v.visit_ty(ty, e, v); for methods.each |m| { visit_method_helper(m, e, v) |
