about summary refs log tree commit diff
path: root/src/comp/syntax
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-12-16 11:37:38 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2011-12-16 13:47:48 +0100
commitd529757515671d5826d8d2203ce0a4f82a3bdee5 (patch)
tree1886bd880e0e912f1d962cd9a1fd1a0035634c66 /src/comp/syntax
parentcff6bdd03616b6f20028ec8568d03363ccc3f9f2 (diff)
downloadrust-d529757515671d5826d8d2203ce0a4f82a3bdee5.tar.gz
rust-d529757515671d5826d8d2203ce0a4f82a3bdee5.zip
Make polymorphic impl methods work
Something will still have to be done to the AST to make it possible to
say `x.foo::<int>()`, since currently field access never allows type
parameters.

Issue #1227
Diffstat (limited to 'src/comp/syntax')
-rw-r--r--src/comp/syntax/ast.rs2
-rw-r--r--src/comp/syntax/fold.rs3
-rw-r--r--src/comp/syntax/parse/parser.rs11
-rw-r--r--src/comp/syntax/visit.rs12
4 files changed, 15 insertions, 13 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index fd79869c27b..d85849b2571 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -423,7 +423,7 @@ tag ret_style {
 
 type _fn = {decl: fn_decl, proto: proto, body: blk};
 
-type method_ = {ident: ident, meth: _fn, id: node_id};
+type method_ = {ident: ident, meth: _fn, id: node_id, tps: [ty_param]};
 
 type method = spanned<method_>;
 
diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs
index aa949b11f34..b3a48cc418c 100644
--- a/src/comp/syntax/fold.rs
+++ b/src/comp/syntax/fold.rs
@@ -246,7 +246,8 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
 }
 
 fn noop_fold_method(m: method_, fld: ast_fold) -> method_ {
-    ret {ident: fld.fold_ident(m.ident), meth: fld.fold_fn(m.meth), id: m.id};
+    ret {ident: fld.fold_ident(m.ident), meth: fld.fold_fn(m.meth)
+         with m};
 }
 
 
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 3d00c333ad4..12df9ecd1ad 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -854,7 +854,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
         while p.peek() != token::RBRACE {
             if eat_word(p, "with") {
                 inner_obj = some(parse_expr(p));
-            } else { meths += [parse_method(p)]; }
+            } else { meths += [parse_method(p, false)]; }
         }
         hi = p.get_hi_pos();
         expect(p, token::RBRACE);
@@ -1832,12 +1832,13 @@ fn parse_anon_obj_field(p: parser) -> ast::anon_obj_field {
     ret {mut: mut, ty: ty, expr: expr, ident: ident, id: p.get_id()};
 }
 
-fn parse_method(p: parser) -> @ast::method {
+fn parse_method(p: parser, allow_tps: bool) -> @ast::method {
     let lo = p.get_lo_pos();
     let proto = parse_method_proto(p);
     let ident = parse_value_ident(p);
+    let tps = allow_tps ? parse_ty_params(p) : [];
     let f = parse_fn(p, proto, ast::impure_fn, ast::il_normal);
-    let meth = {ident: ident, meth: f, id: p.get_id()};
+    let meth = {ident: ident, meth: f, id: p.get_id(), tps: tps};
     ret @spanned(lo, f.body.span.hi, meth);
 }
 
@@ -1850,7 +1851,7 @@ fn parse_item_obj(p: parser, attrs: [ast::attribute]) -> @ast::item {
                   parse_obj_field, p);
     let meths: [@ast::method] = [];
     expect(p, token::LBRACE);
-    while p.peek() != token::RBRACE { meths += [parse_method(p)]; }
+    while p.peek() != token::RBRACE { meths += [parse_method(p, false)]; }
     let hi = p.get_hi_pos();
     expect(p, token::RBRACE);
     let ob: ast::_obj = {fields: fields.node, methods: meths};
@@ -1864,7 +1865,7 @@ fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
     expect_word(p, "for");
     let ty = parse_ty(p, false), meths = [];
     expect(p, token::LBRACE);
-    while !eat(p, token::RBRACE) { meths += [parse_method(p)]; }
+    while !eat(p, token::RBRACE) { meths += [parse_method(p, true)]; }
     ret mk_item(p, lo, p.get_last_hi_pos(), ident,
                 ast::item_impl(tps, ty, meths), attrs);
 }
diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs
index 5091c2d9ea0..a1feec5bec9 100644
--- a/src/comp/syntax/visit.rs
+++ b/src/comp/syntax/visit.rs
@@ -101,15 +101,15 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
       item_obj(ob, _, _) {
         for f: obj_field in ob.fields { v.visit_ty(f.ty, e, v); }
         for m: @method in ob.methods {
-            v.visit_fn(m.node.meth, [], m.span, some(m.node.ident), m.node.id,
-                       e, v);
+            v.visit_fn(m.node.meth, m.node.tps, m.span, some(m.node.ident),
+                       m.node.id, e, v);
         }
       }
       item_impl(_, ty, methods) {
         visit_ty(ty, e, v);
         for m in methods {
-            v.visit_fn(m.node.meth, [], m.span, some(m.node.ident), m.node.id,
-                       e, v);
+            v.visit_fn(m.node.meth, m.node.tps, m.span, some(m.node.ident),
+                       m.node.id, e, v);
         }
       }
     }
@@ -321,8 +321,8 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
           some(ex) { v.visit_expr(ex, e, v); }
         }
         for m: @method in anon_obj.methods {
-            v.visit_fn(m.node.meth, [], m.span, some(m.node.ident), m.node.id,
-                       e, v);
+            v.visit_fn(m.node.meth, m.node.tps, m.span, some(m.node.ident),
+                       m.node.id, e, v);
         }
       }
       expr_mac(mac) { visit_mac(mac, e, v); }