about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax/parse/parser.rs29
-rw-r--r--src/test/run-pass/new-impl-syntax.rs26
2 files changed, 49 insertions, 6 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 0bd08250617..19a52c3550f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2791,8 +2791,9 @@ impl Parser {
         (ident, item_trait(tps, traits, meths), None)
     }
 
-    // Parses four variants (with the region/type params always optional):
+    // Parses two variants (with the region/type params always optional):
     //    impl<T> ~[T] : to_str { ... }
+    //    impl<T> to_str for ~[T] { ... }
     fn parse_item_impl() -> item_info {
         fn wrap_path(p: Parser, pt: @path) -> @Ty {
             @Ty {
@@ -2802,8 +2803,6 @@ impl Parser {
             }
         }
 
-        // We do two separate paths here: old-style impls and new-style impls.
-
         // First, parse type parameters if necessary.
         let mut tps;
         if self.token == token::LT {
@@ -2816,14 +2815,32 @@ impl Parser {
         // XXX: clownshoes
         let ident = special_idents::clownshoes_extensions;
 
-        // Parse the type.
-        let ty = self.parse_ty(false);
-
+        // Parse the type. (If this is `impl trait for type`, however, this
+        // actually parses the trait.)
+        let mut ty = self.parse_ty(false);
 
         // Parse traits, if necessary.
         let opt_trait = if self.token == token::COLON {
+            // Old-style trait.
             self.bump();
             Some(self.parse_trait_ref())
+        } else if self.eat_keyword(~"for") {
+            // New-style trait. Reinterpret the type as a trait.
+            let opt_trait_ref = match ty.node {
+                ty_path(path, node_id) => {
+                    Some(@trait_ref {
+                        path: path,
+                        ref_id: node_id
+                    })
+                }
+                _ => {
+                    self.span_err(copy self.span, ~"not a trait");
+                    None
+                }
+            };
+
+            ty = self.parse_ty(false);
+            opt_trait_ref
         } else {
             None
         };
diff --git a/src/test/run-pass/new-impl-syntax.rs b/src/test/run-pass/new-impl-syntax.rs
new file mode 100644
index 00000000000..4cb30ffa213
--- /dev/null
+++ b/src/test/run-pass/new-impl-syntax.rs
@@ -0,0 +1,26 @@
+struct Thingy {
+    x: int,
+    y: int
+}
+
+impl ToStr for Thingy {
+    pure fn to_str() -> ~str {
+        fmt!("{ x: %d, y: %d }", self.x, self.y)
+    }
+}
+
+struct PolymorphicThingy<T> {
+    x: T
+}
+
+impl<T:ToStr> ToStr for PolymorphicThingy<T> {
+    pure fn to_str() -> ~str {
+        self.x.to_str()
+    }
+}
+
+fn main() {
+    io::println(Thingy { x: 1, y: 2 }.to_str());
+    io::println(PolymorphicThingy { x: Thingy { x: 1, y: 2 } }.to_str());
+}
+