about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-07-18 09:31:53 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-07-18 16:05:17 -0700
commit3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac (patch)
tree0613184ab1f468f2a1b776c1d4c6df4ac15d69db /src/libsyntax
parent1528256fdc26199dd58b390e42e2d0dc53b9703d (diff)
downloadrust-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.rs6
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs1
-rw-r--r--src/libsyntax/parse/parser.rs29
-rw-r--r--src/libsyntax/print/pprust.rs10
-rw-r--r--src/libsyntax/visit.rs6
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)