Skip to content

Commit 6c1c5b3

Browse files
lkupergraydon
authored andcommitted
More progress on anonymous objects.
Still segfaulting on the method-overriding.rs test, though.
1 parent 6a53e39 commit 6c1c5b3

File tree

5 files changed

+100
-14
lines changed

5 files changed

+100
-14
lines changed

src/comp/front/parser.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -807,24 +807,24 @@ fn parse_bottom_expr(parser p) -> @ast::expr {
807807

808808
// Only make people type () if they're actually adding new fields
809809
let option.t[vec[ast.obj_field]] fields = none[vec[ast.obj_field]];
810-
if (p.peek() == token.LPAREN) {
810+
if (p.peek() == token::LPAREN) {
811811
auto pf = parse_obj_field;
812812
hi = p.get_hi_pos();
813-
expect(p, token.LPAREN);
813+
expect(p, token::LPAREN);
814814
fields = some[vec[ast.obj_field]]
815815
(parse_seq_to_end[ast.obj_field]
816-
(token.RPAREN,
817-
some(token.COMMA),
816+
(token::RPAREN,
817+
some(token::COMMA),
818818
pf, hi, p));
819819
}
820820

821821
let vec[@ast.method] meths = vec();
822822
let option.t[ast.ident] with_obj = none[ast.ident];
823823

824-
expect(p, token.LBRACE);
825-
while (p.peek() != token.RBRACE) {
824+
expect(p, token::LBRACE);
825+
while (p.peek() != token::RBRACE) {
826826
alt (p.peek()) {
827-
case (token.WITH) {
827+
case (token::WITH) {
828828
with_obj = some[ast.ident](parse_ident(p));
829829
}
830830
case (_) {
@@ -833,7 +833,7 @@ fn parse_bottom_expr(parser p) -> @ast::expr {
833833
}
834834
}
835835
hi = p.get_hi_pos();
836-
expect(p, token.RBRACE);
836+
expect(p, token::RBRACE);
837837

838838
// fields and methods may be *additional* or *overriding* fields and
839839
// 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 {
848848
auto odid = rec(ty=p.next_def_id(), ctor=p.next_def_id());
849849

850850
ex = ast.expr_anon_obj(ob, ty_params, odid, ast.ann_none);
851+
851852
} else if (eat_word(p, "bind")) {
852853
auto e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS);
853854
fn parse_expr_opt(parser p) -> option::t[@ast::expr] {

src/comp/middle/fold.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ type ast_fold[ENV] =
209209
(fn(&ENV e, &span sp,
210210
&@expr e, &ann a) -> @expr) fold_expr_chan,
211211

212+
(fn(&ENV e, &span sp,
213+
&ast.anon_obj ob, // TODO: Is the ob arg supposed to be & or not?
214+
vec[ast.ty_param] tps,
215+
ast.obj_def_ids odid, ann a) -> @expr) fold_expr_anon_obj,
212216

213217
// Decl folds.
214218
(fn(&ENV e, &span sp,
@@ -322,6 +326,11 @@ type ast_fold[ENV] =
322326
&option::t[@ast::method] dtor)
323327
-> ast::_obj) fold_obj,
324328

329+
(fn(&ENV e,
330+
Option.t[vec[ast.obj_field]] fields,
331+
vec[@ast.method] methods,
332+
Option.t[ident] with_obj) -> ast.anon_obj) fold_anon_obj,
333+
325334
// Env updates.
326335
(fn(&ENV e, &@ast::crate c) -> ENV) update_env_for_crate,
327336
(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 {
828837
auto t2 = fld.fold_ann(env_, t);
829838
ret fld.fold_expr_chan(env_, e.span, ee, t2);
830839
}
840+
841+
case (ast.expr_anon_obj(?ob, ?tps, ?odid, ?t)) {
842+
auto ee = fold_anon_obj(env_, fld, ob);
843+
auto t2 = fld.fold_ann(env_, t);
844+
ret fld.fold_expr_anon_obj(env_, e.span, ee, tps, odid, t2);
845+
}
831846
}
832847

833848
fail;
@@ -930,7 +945,6 @@ fn fold_method[ENV](&ENV env, &ast_fold[ENV] fld,
930945
ret @rec(node=rec(meth=meth with m.node) with *m);
931946
}
932947

933-
934948
fn fold_obj[ENV](&ENV env, &ast_fold[ENV] fld, &ast::_obj ob) -> ast::_obj {
935949

936950
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 {
962976
ret fld.fold_obj(env, fields, meths, dtor);
963977
}
964978

979+
fn fold_anon_obj[ENV](&ENV env, ast_fold[ENV] fld, &ast.anon_obj ob)
980+
-> ast.anon_obj {
981+
982+
// Fields
983+
let Option.t[vec[ast.obj_field]] fields = none[vec[ast.obj_field]];
984+
alt (ob.fields) {
985+
case (none[vec[ast.obj_field]]) { }
986+
case (some[vec[ast.obj_field]](?v)) {
987+
let vec[ast.obj_field] fields = vec();
988+
for (ast.obj_field f in v) {
989+
fields += vec(fold_obj_field(env, fld, f));
990+
}
991+
}
992+
}
993+
994+
// with_obj
995+
let Option.t[ast.ident] with_obj = none[ast.ident];
996+
alt (ob.with_obj) {
997+
case (none[ast.ident]) { }
998+
case (some[ast.ident](?i)) {
999+
with_obj = some[ast.ident](i);
1000+
}
1001+
}
1002+
1003+
// Methods
1004+
let vec[@ast.method] meths = vec();
1005+
let vec[ast.ty_param] tp = vec();
1006+
for (@ast.method m in ob.methods) {
1007+
// Fake-up an ast.item for this method.
1008+
// FIXME: this is kinda awful. Maybe we should reformulate
1009+
// the way we store methods in the AST?
1010+
let @ast.item i = @rec(node=ast.item_fn(m.node.ident,
1011+
m.node.meth,
1012+
tp,
1013+
m.node.id,
1014+
m.node.ann),
1015+
span=m.span);
1016+
let ENV _env = fld.update_env_for_item(env, i);
1017+
Vec.push[@ast.method](meths, fold_method(_env, fld, m));
1018+
}
1019+
ret fld.fold_anon_obj(env, fields, meths, with_obj);
1020+
}
1021+
9651022
fn fold_view_item[ENV](&ENV env, &ast_fold[ENV] fld, &@view_item vi)
9661023
-> @view_item {
9671024

@@ -1410,6 +1467,12 @@ fn identity_fold_expr_chan[ENV](&ENV e, &span sp, &@expr x,
14101467
ret @respan(sp, ast::expr_chan(x, a));
14111468
}
14121469

1470+
fn identity_fold_expr_anon_obj[ENV](&ENV e, &span sp,
1471+
&ast.anon_obj ob, vec[ast.ty_param] tps,
1472+
ast.obj_def_ids odid, ann a) -> @expr {
1473+
ret @respan(sp, ast.expr_anon_obj(ob, tps, odid, a));
1474+
}
1475+
14131476
// Decl identities.
14141477

14151478
fn identity_fold_decl_local[ENV](&ENV e, &span sp,
@@ -1584,6 +1647,12 @@ fn identity_fold_obj[ENV](&ENV e,
15841647
ret rec(fields=fields, methods=methods, dtor=dtor);
15851648
}
15861649

1650+
fn identity_fold_anon_obj[ENV](&ENV e,
1651+
Option.t[vec[ast.obj_field]] fields,
1652+
vec[@ast.method] methods,
1653+
Option.t[ident] with_obj) -> ast.anon_obj {
1654+
ret rec(fields=fields, methods=methods, with_obj=with_obj);
1655+
}
15871656

15881657
// Env update identities.
15891658

@@ -1707,6 +1776,9 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
17071776
fold_expr_port = bind identity_fold_expr_port[ENV](_,_,_),
17081777
fold_expr_chan = bind identity_fold_expr_chan[ENV](_,_,_,_),
17091778

1779+
fold_expr_anon_obj
1780+
= bind identity_fold_expr_anon_obj[ENV](_,_,_,_,_,_),
1781+
17101782
fold_decl_local = bind identity_fold_decl_local[ENV](_,_,_),
17111783
fold_decl_item = bind identity_fold_decl_item[ENV](_,_,_),
17121784

@@ -1746,6 +1818,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
17461818
fold_native_mod = bind identity_fold_native_mod[ENV](_,_),
17471819
fold_crate = bind identity_fold_crate[ENV](_,_,_,_),
17481820
fold_obj = bind identity_fold_obj[ENV](_,_,_,_),
1821+
fold_anon_obj = bind identity_fold_anon_obj[ENV](_,_,_,_),
17491822

17501823
update_env_for_crate = bind identity_update_env_for_crate[ENV](_,_),
17511824
update_env_for_item = bind identity_update_env_for_item[ENV](_,_),

src/comp/middle/trans.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,10 +2885,14 @@ fn iter_sequence(@block_ctxt cx,
28852885
auto et = ty::mk_mach(cx.fcx.lcx.ccx.tcx, common::ty_u8);
28862886
ret iter_sequence_body(cx, v, et, f, true);
28872887
}
2888-
case (_) { fail; }
2888+
case (_) {
2889+
2890+
cx.fcx.lcx.ccx.sess.bug("unexpected type in " +
2891+
"trans::iter_sequence: " +
2892+
ty.ty_to_str(cx.fcx.lcx.ccx.tcx, t));
2893+
fail;
2894+
}
28892895
}
2890-
cx.fcx.lcx.ccx.sess.bug("bad type in trans::iter_sequence");
2891-
fail;
28922896
}
28932897

28942898
fn lazily_emit_all_tydesc_glue(&@block_ctxt cx,

src/comp/middle/ty.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,7 @@ fn pat_ty(&ctxt cx, &node_type_table ntt, &@ast::pat pat) -> t {
16591659
fail; // not reached
16601660
}
16611661

1662+
<<<<<<< HEAD
16621663
fn expr_ann(&@ast::expr e) -> ast::ann {
16631664
alt (e.node) {
16641665
case (ast::expr_vec(_,_,?a)) { ret a; }
@@ -1694,6 +1695,7 @@ fn expr_ann(&@ast::expr e) -> ast::ann {
16941695
case (ast::expr_check(_,?a)) { ret a; }
16951696
case (ast::expr_port(?a)) { ret a; }
16961697
case (ast::expr_chan(_,?a)) { ret a; }
1698+
case (ast::expr_anon_obj(_,_,_,?a)) { ret a; }
16971699
case (ast::expr_break(?a)) { ret a; }
16981700
case (ast::expr_cont(?a)) { ret a; }
16991701
case (ast::expr_self_method(_, ?a)) { ret a; }

src/test/run-pass/method-overriding.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// xfail-boot
22
// xfail-stage0
33
use std;
4-
import std._vec.len;
4+
55
fn main() {
66

77
obj a() {
@@ -15,12 +15,18 @@ fn main() {
1515

1616
auto my_a = a();
1717

18-
// Step 1 is to add support for this "with" syntax
18+
// Extending an object with a new method
1919
auto my_b = obj {
2020
fn baz() -> int {
2121
ret self.foo();
2222
}
2323
with my_a
2424
};
25+
26+
// Extending an object with a new field
27+
auto my_c = obj(quux) { with my_a } ;
28+
29+
// Should this be legal?
30+
auto my_d = obj() { with my_a } ;
2531

2632
}

0 commit comments

Comments
 (0)