about summary refs log tree commit diff
path: root/src/comp/syntax/parse
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2012-01-03 15:29:28 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2012-01-03 15:37:41 +0100
commit506a6ec38b4e5f5fc80d8c6bfc388e5cdba4d772 (patch)
tree6b9919a8ead303d129dc04f0e0745b410a1fd91a /src/comp/syntax/parse
parente1dc40b2717c3469a52d3b8ae31b377dbd6e4d60 (diff)
downloadrust-506a6ec38b4e5f5fc80d8c6bfc388e5cdba4d772.tar.gz
rust-506a6ec38b4e5f5fc80d8c6bfc388e5cdba4d772.zip
Make syntax for impls less magical
The trick of interpreting parameters to the iface type as parameters
to the impl was just too magical.

Issue #1227
Diffstat (limited to 'src/comp/syntax/parse')
-rw-r--r--src/comp/syntax/parse/parser.rs41
1 files changed, 18 insertions, 23 deletions
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index dd649779235..1036b8e9f92 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -1850,34 +1850,29 @@ fn parse_item_iface(p: parser, attrs: [ast::attribute]) -> @ast::item {
                 ast::item_iface(tps, meths), attrs);
 }
 
+// Parses three variants (with the initial params always optional):
+//    impl <T: copy> of to_str for [T] { ... }
+//    impl name<T> of to_str for [T] { ... }
+//    impl name<T> for [T] { ... }
 fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
-    let lo = p.get_last_lo_pos(), ident, tps, ifce;
+    let lo = p.get_last_lo_pos();
     fn wrap_path(p: parser, pt: @ast::path) -> @ast::ty {
         @{node: ast::ty_path(pt, p.get_id()), span: pt.span}
     }
-    if eat_word(p, "of") {
+    let (ident, tps) = if !is_word(p, "of") {
+        if p.peek() == token::LT { (none, parse_ty_params(p)) }
+        else { (some(parse_ident(p)), parse_ty_params(p)) }
+    } else { (none, []) };
+    let ifce = if eat_word(p, "of") {
         let path = parse_path_and_ty_param_substs(p, false);
-        tps = vec::map(path.node.types, {|tp|
-            alt tp.node {
-              ast::ty_path(pt, _) {
-                if vec::len(pt.node.idents) == 1u &&
-                   vec::len(pt.node.types) == 0u {
-                     ret {ident: pt.node.idents[0], id: p.get_id(),
-                          bounds: @[]};
-                }
-              }
-              _ {}
-            }
-            p.fatal("only single-word, parameter-less types allowed here");
-        });
-        ident = path.node.idents[vec::len(path.node.idents)-1u];
-        ifce = some(wrap_path(p, path));
-    } else {
-        ident = parse_ident(p);
-        tps = parse_ty_params(p);
-        ifce = if eat_word(p, "of") {
-            some(wrap_path(p, parse_path_and_ty_param_substs(p, false)))
-        } else { none };
+        if option::is_none(ident) {
+            ident = some(path.node.idents[vec::len(path.node.idents) - 1u]);
+        }
+        some(wrap_path(p, path))
+    } else { none };
+    let ident = alt ident {
+        some(name) { name }
+        none. { expect_word(p, "of"); fail; }
     };
     expect_word(p, "for");
     let ty = parse_ty(p, false), meths = [];