about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorLindsey Kuper <lkuper@mozilla.com>2011-05-10 19:52:22 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-05-13 17:35:13 -0700
commit6c1c5b39482158f078b5b10164c024edf345e386 (patch)
tree7c179784c98b97df43ff2329c96940452934f7b4 /src/comp
parent6a53e39e710d4a31785015d042cc491692954ab7 (diff)
downloadrust-6c1c5b39482158f078b5b10164c024edf345e386.tar.gz
rust-6c1c5b39482158f078b5b10164c024edf345e386.zip
More progress on anonymous objects.
Still segfaulting on the method-overriding.rs test, though.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/parser.rs17
-rw-r--r--src/comp/middle/fold.rs75
-rw-r--r--src/comp/middle/trans.rs10
-rw-r--r--src/comp/middle/ty.rs2
4 files changed, 92 insertions, 12 deletions
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index cb7435d8132..267c752ee1f 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -807,24 +807,24 @@ fn parse_bottom_expr(parser p) -> @ast::expr {
 
         // Only make people type () if they're actually adding new fields
         let option.t[vec[ast.obj_field]] fields = none[vec[ast.obj_field]];
-        if (p.peek() == token.LPAREN) {
+        if (p.peek() == token::LPAREN) {
             auto pf = parse_obj_field;
             hi = p.get_hi_pos();
-            expect(p, token.LPAREN);
+            expect(p, token::LPAREN);
             fields = some[vec[ast.obj_field]]
                 (parse_seq_to_end[ast.obj_field] 
-                 (token.RPAREN,
-                  some(token.COMMA),
+                 (token::RPAREN,
+                  some(token::COMMA),
                   pf, hi, p));
         }
 
         let vec[@ast.method] meths = vec();
         let option.t[ast.ident] with_obj = none[ast.ident];
 
-        expect(p, token.LBRACE);
-        while (p.peek() != token.RBRACE) {
+        expect(p, token::LBRACE);
+        while (p.peek() != token::RBRACE) {
             alt (p.peek()) {
-                case (token.WITH) { 
+                case (token::WITH) { 
                     with_obj = some[ast.ident](parse_ident(p));
                 }
                 case (_) {
@@ -833,7 +833,7 @@ fn parse_bottom_expr(parser p) -> @ast::expr {
             }
         }
         hi = p.get_hi_pos();
-        expect(p, token.RBRACE);
+        expect(p, token::RBRACE);
 
         // fields and methods may be *additional* or *overriding* fields and
         // methods if there's a with_obj, or they may be the *only* fields and
@@ -848,6 +848,7 @@ fn parse_bottom_expr(parser p) -> @ast::expr {
         auto odid = rec(ty=p.next_def_id(), ctor=p.next_def_id());
 
         ex = ast.expr_anon_obj(ob, ty_params, odid, ast.ann_none);
+
     } else if (eat_word(p, "bind")) {
         auto e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS);
         fn parse_expr_opt(parser p) -> option::t[@ast::expr] {
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 5af85f14cbb..7d0fa9946a0 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -209,6 +209,10 @@ type ast_fold[ENV] =
      (fn(&ENV e, &span sp,
          &@expr e, &ann a) -> @expr)              fold_expr_chan,
 
+     (fn(&ENV e, &span sp,
+         &ast.anon_obj ob, // TODO: Is the ob arg supposed to be & or not?
+         vec[ast.ty_param] tps,
+         ast.obj_def_ids odid, ann a) -> @expr)   fold_expr_anon_obj,
 
      // Decl folds.
      (fn(&ENV e, &span sp,
@@ -322,6 +326,11 @@ type ast_fold[ENV] =
          &option::t[@ast::method] dtor)
       -> ast::_obj)                                fold_obj,
 
+     (fn(&ENV e,
+         Option.t[vec[ast.obj_field]] fields,
+         vec[@ast.method] methods,
+         Option.t[ident] with_obj) -> ast.anon_obj) fold_anon_obj,
+
      // Env updates.
      (fn(&ENV e, &@ast::crate c) -> ENV) update_env_for_crate,
      (fn(&ENV e, &@item i) -> ENV) update_env_for_item,
@@ -828,6 +837,12 @@ fn fold_expr[ENV](&ENV env, &ast_fold[ENV] fld, &@expr e) -> @expr {
             auto t2 = fld.fold_ann(env_, t);
             ret fld.fold_expr_chan(env_, e.span, ee, t2);
         }
+
+        case (ast.expr_anon_obj(?ob, ?tps, ?odid, ?t)) {
+            auto ee = fold_anon_obj(env_, fld, ob);
+            auto t2 = fld.fold_ann(env_, t);
+            ret fld.fold_expr_anon_obj(env_, e.span, ee, tps, odid, t2);
+        }
     }
 
     fail;
@@ -930,7 +945,6 @@ fn fold_method[ENV](&ENV env, &ast_fold[ENV] fld,
     ret @rec(node=rec(meth=meth with m.node) with *m);
 }
 
-
 fn fold_obj[ENV](&ENV env, &ast_fold[ENV] fld, &ast::_obj ob) -> ast::_obj {
 
     let vec[ast::obj_field] fields = vec();
@@ -962,6 +976,49 @@ fn fold_obj[ENV](&ENV env, &ast_fold[ENV] fld, &ast::_obj ob) -> ast::_obj {
     ret fld.fold_obj(env, fields, meths, dtor);
 }
 
+fn fold_anon_obj[ENV](&ENV env, ast_fold[ENV] fld, &ast.anon_obj ob) 
+    -> ast.anon_obj {
+
+    // Fields
+    let Option.t[vec[ast.obj_field]] fields = none[vec[ast.obj_field]];
+    alt (ob.fields) {
+        case (none[vec[ast.obj_field]]) { }
+        case (some[vec[ast.obj_field]](?v)) {
+            let vec[ast.obj_field] fields = vec();
+            for (ast.obj_field f in v) {
+                fields += vec(fold_obj_field(env, fld, f));
+            }
+        }
+    }
+
+    // with_obj
+    let Option.t[ast.ident] with_obj = none[ast.ident];
+    alt (ob.with_obj) {
+        case (none[ast.ident]) { }
+        case (some[ast.ident](?i)) {
+            with_obj = some[ast.ident](i);
+        }
+    }
+
+    // Methods
+    let vec[@ast.method] meths = vec();
+    let vec[ast.ty_param] tp = vec();
+    for (@ast.method m in ob.methods) {
+        // Fake-up an ast.item for this method.
+        // FIXME: this is kinda awful. Maybe we should reformulate
+        // the way we store methods in the AST?
+        let @ast.item i = @rec(node=ast.item_fn(m.node.ident,
+                                                m.node.meth,
+                                                tp,
+                                                m.node.id,
+                                                m.node.ann),
+                               span=m.span);
+        let ENV _env = fld.update_env_for_item(env, i);
+        Vec.push[@ast.method](meths, fold_method(_env, fld, m));
+    }
+    ret fld.fold_anon_obj(env, fields, meths, with_obj);
+}
+
 fn fold_view_item[ENV](&ENV env, &ast_fold[ENV] fld, &@view_item vi)
     -> @view_item {
 
@@ -1410,6 +1467,12 @@ fn identity_fold_expr_chan[ENV](&ENV e, &span sp, &@expr x,
     ret @respan(sp, ast::expr_chan(x, a));
 }
 
+fn identity_fold_expr_anon_obj[ENV](&ENV e, &span sp,
+                                    &ast.anon_obj ob, vec[ast.ty_param] tps,
+                                    ast.obj_def_ids odid, ann a) -> @expr {
+    ret @respan(sp, ast.expr_anon_obj(ob, tps, odid, a));
+}
+
 // Decl identities.
 
 fn identity_fold_decl_local[ENV](&ENV e, &span sp,
@@ -1584,6 +1647,12 @@ fn identity_fold_obj[ENV](&ENV e,
     ret rec(fields=fields, methods=methods, dtor=dtor);
 }
 
+fn identity_fold_anon_obj[ENV](&ENV e,
+                               Option.t[vec[ast.obj_field]] fields,
+                               vec[@ast.method] methods,
+                               Option.t[ident] with_obj) -> ast.anon_obj {
+    ret rec(fields=fields, methods=methods, with_obj=with_obj);
+}
 
 // Env update identities.
 
@@ -1707,6 +1776,9 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
          fold_expr_port   = bind identity_fold_expr_port[ENV](_,_,_),
          fold_expr_chan   = bind identity_fold_expr_chan[ENV](_,_,_,_),
 
+         fold_expr_anon_obj   
+                        = bind identity_fold_expr_anon_obj[ENV](_,_,_,_,_,_),
+
          fold_decl_local  = bind identity_fold_decl_local[ENV](_,_,_),
          fold_decl_item   = bind identity_fold_decl_item[ENV](_,_,_),
 
@@ -1746,6 +1818,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
          fold_native_mod = bind identity_fold_native_mod[ENV](_,_),
          fold_crate = bind identity_fold_crate[ENV](_,_,_,_),
          fold_obj = bind identity_fold_obj[ENV](_,_,_,_),
+         fold_anon_obj = bind identity_fold_anon_obj[ENV](_,_,_,_),
 
          update_env_for_crate = bind identity_update_env_for_crate[ENV](_,_),
          update_env_for_item = bind identity_update_env_for_item[ENV](_,_),
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 4f1636d4b50..fa50d857ae9 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -2885,10 +2885,14 @@ fn iter_sequence(@block_ctxt cx,
             auto et = ty::mk_mach(cx.fcx.lcx.ccx.tcx, common::ty_u8);
             ret iter_sequence_body(cx, v, et, f, true);
         }
-        case (_) { fail; }
+        case (_) {
+
+            cx.fcx.lcx.ccx.sess.bug("unexpected type in " +
+                                    "trans::iter_sequence: " +
+                                    ty.ty_to_str(cx.fcx.lcx.ccx.tcx, t));
+            fail; 
+        }
     }
-    cx.fcx.lcx.ccx.sess.bug("bad type in trans::iter_sequence");
-    fail;
 }
 
 fn lazily_emit_all_tydesc_glue(&@block_ctxt cx,
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index a0c3a724c3e..fcde5e2cb89 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -1659,6 +1659,7 @@ fn pat_ty(&ctxt cx, &node_type_table ntt, &@ast::pat pat) -> t {
     fail;   // not reached
 }
 
+<<<<<<< HEAD
 fn expr_ann(&@ast::expr e) -> ast::ann {
     alt (e.node) {
         case (ast::expr_vec(_,_,?a)) { ret a; }
@@ -1694,6 +1695,7 @@ fn expr_ann(&@ast::expr e) -> ast::ann {
         case (ast::expr_check(_,?a)) { ret a; }
         case (ast::expr_port(?a)) { ret a; }
         case (ast::expr_chan(_,?a)) { ret a; }
+        case (ast::expr_anon_obj(_,_,_,?a)) { ret a; }
         case (ast::expr_break(?a)) { ret a; }
         case (ast::expr_cont(?a)) { ret a; }
         case (ast::expr_self_method(_, ?a)) { ret a; }