From 54dd28a9d2006e1c52e0be4ecd39b713617dc284 Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Fri, 6 May 2011 17:08:41 -0700 Subject: [PATCH 1/8] Starting on support for anonymous objects. Just syntax so far. --- src/comp/front/ast.rs | 20 +++++++++++ src/comp/front/parser.rs | 50 ++++++++++++++++++++++++++ src/test/run-pass/method-overriding.rs | 26 ++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 src/test/run-pass/method-overriding.rs diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 5e5185bf7eeac..51977b5f7fbfc 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -296,6 +296,7 @@ tag expr_ { expr_check(@expr, ann); expr_port(ann); expr_chan(@expr, ann); + expr_anon_obj(anon_obj, vec[ty_param], obj_def_ids, ann); } type lit = spanned[lit_]; @@ -371,6 +372,25 @@ type _obj = rec(vec[obj_field] fields, vec[@method] methods, option::t[@method] dtor); + +// Hmm. An anon_obj might extend an existing object, in which case it'll +// probably add fields and methods. +type anon_obj = rec(option.t[vec[obj_field]] fields, + vec[@method] methods, + option.t[ident] with_obj); + +tag mod_index_entry { + mie_view_item(@view_item); + mie_item(@item); + mie_tag_variant(@item /* tag item */, uint /* variant index */); +} + +tag native_mod_index_entry { + nmie_view_item(@view_item); + nmie_item(@native_item); +} + +type mod_index = hashmap[ident,mod_index_entry]; type _mod = rec(vec[@view_item] view_items, vec[@item] items); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 520090a52c797..f395ea16f3d62 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -799,6 +799,56 @@ fn parse_bottom_expr(parser p) -> @ast::expr { } ex = ast::expr_rec(fields, base, p.get_ann()); + } + // Anonymous object + else if (eat_word(p, "obj")) { + + // FIXME: Can anonymous objects have ty params? + auto ty_params = parse_ty_params(p); + + // 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) { + auto pf = parse_obj_field; + hi = p.get_hi_pos(); + expect(p, token.LPAREN); + fields = some[vec[ast.obj_field]] + (parse_seq_to_end[ast.obj_field] + (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) { + alt (p.peek()) { + case (token.WITH) { + with_obj = some[ast.ident](parse_ident(p)); + } + case (_) { + // fall through + } + } + } + hi = p.get_hi_pos(); + 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 methods if there's no with_obj. + + // We don't need to pull ".node" out of fields because it's not a + // "spanned". + let ast.anon_obj ob = rec(fields=fields, + methods=meths, + with_obj=with_obj); + + 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/test/run-pass/method-overriding.rs b/src/test/run-pass/method-overriding.rs new file mode 100644 index 0000000000000..bf68ddd1e4289 --- /dev/null +++ b/src/test/run-pass/method-overriding.rs @@ -0,0 +1,26 @@ +// xfail-boot +// xfail-stage0 +use std; +import std._vec.len; +fn main() { + + obj a() { + fn foo() -> int { + ret 2; + } + fn bar() -> int { + ret self.foo(); + } + } + + auto my_a = a(); + + // Step 1 is to add support for this "with" syntax + auto my_b = obj { + fn baz() -> int { + ret self.foo(); + } + with my_a + }; + +} From 5978b429e92c58033dffd71be9a8b8525817df01 Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Tue, 10 May 2011 11:55:32 -0700 Subject: [PATCH 2/8] Correct capitalization of "Option". --- src/comp/front/ast.rs | 12 ++++++------ src/comp/front/parser.rs | 7 +++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 51977b5f7fbfc..d2bc657880c83 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -372,12 +372,12 @@ type _obj = rec(vec[obj_field] fields, vec[@method] methods, option::t[@method] dtor); - -// Hmm. An anon_obj might extend an existing object, in which case it'll -// probably add fields and methods. -type anon_obj = rec(option.t[vec[obj_field]] fields, - vec[@method] methods, - option.t[ident] with_obj); +type anon_obj = rec( + // New fields and methods, if they exist. + Option.t[vec[obj_field]] fields, + vec[@method] methods, + // with_obj: the original object being extended, if it exists. + Option.t[ident] with_obj); tag mod_index_entry { mie_view_item(@view_item); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index f395ea16f3d62..cb7435d8132c9 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -795,7 +795,6 @@ fn parse_bottom_expr(parser p) -> @ast::expr { } else { unexpected(p, p.peek()); } - } ex = ast::expr_rec(fields, base, p.get_ann()); @@ -836,9 +835,9 @@ fn parse_bottom_expr(parser p) -> @ast::expr { hi = p.get_hi_pos(); 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 methods if there's no with_obj. + // 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 + // methods if there's no with_obj. // We don't need to pull ".node" out of fields because it's not a // "spanned". From 6eceded509d799ec3b9ae3f37d4f33a12b118cef Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Tue, 10 May 2011 19:52:22 -0700 Subject: [PATCH 3/8] More progress on anonymous objects. Still segfaulting on the method-overriding.rs test, though. --- src/comp/front/parser.rs | 17 +++--- src/comp/middle/fold.rs | 75 +++++++++++++++++++++++++- src/comp/middle/trans.rs | 10 ++-- src/comp/middle/ty.rs | 2 + src/test/run-pass/method-overriding.rs | 10 +++- 5 files changed, 100 insertions(+), 14 deletions(-) diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index cb7435d8132c9..267c752ee1fee 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 5af85f14cbbc3..7d0fa9946a0e8 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 4f1636d4b50ef..fa50d857ae908 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 5957c1fdf3683..31d6b2c888ed3 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1675,6 +1675,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; } @@ -1710,6 +1711,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; } diff --git a/src/test/run-pass/method-overriding.rs b/src/test/run-pass/method-overriding.rs index bf68ddd1e4289..3fbb53ff6cfd7 100644 --- a/src/test/run-pass/method-overriding.rs +++ b/src/test/run-pass/method-overriding.rs @@ -1,7 +1,7 @@ // xfail-boot // xfail-stage0 use std; -import std._vec.len; + fn main() { obj a() { @@ -15,12 +15,18 @@ fn main() { auto my_a = a(); - // Step 1 is to add support for this "with" syntax + // Extending an object with a new method auto my_b = obj { fn baz() -> int { ret self.foo(); } with my_a }; + + // Extending an object with a new field + auto my_c = obj(quux) { with my_a } ; + + // Should this be legal? + auto my_d = obj() { with my_a } ; } From f84542fddd73ce2bcb27ea6986db7612e76e4e59 Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Wed, 11 May 2011 12:04:58 -0700 Subject: [PATCH 4/8] Bug fixes. Fixed infinite loop on anonymous objects in parser; added expr_anon_obj to walk.rs; fixed syntax of test case. --- src/comp/front/ast.rs | 12 ----------- src/comp/front/parser.rs | 30 +++++++++++++++++++------- src/comp/middle/walk.rs | 2 ++ src/test/run-pass/method-overriding.rs | 2 +- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index d2bc657880c83..eda09276184ce 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -379,18 +379,6 @@ type anon_obj = rec( // with_obj: the original object being extended, if it exists. Option.t[ident] with_obj); -tag mod_index_entry { - mie_view_item(@view_item); - mie_item(@item); - mie_tag_variant(@item /* tag item */, uint /* variant index */); -} - -tag native_mod_index_entry { - nmie_view_item(@view_item); - nmie_item(@native_item); -} - -type mod_index = hashmap[ident,mod_index_entry]; type _mod = rec(vec[@view_item] view_items, vec[@item] items); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 267c752ee1fee..a02a2fa4b0b81 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -806,26 +806,40 @@ fn parse_bottom_expr(parser p) -> @ast::expr { auto ty_params = parse_ty_params(p); // Only make people type () if they're actually adding new fields - let option.t[vec[ast.obj_field]] fields = none[vec[ast.obj_field]]; + let option.t[vec[ast::obj_field]] fields = none[vec[ast::obj_field]]; if (p.peek() == token::LPAREN) { auto pf = parse_obj_field; + expect(p, token::LBRACE); + while (p.peek() != token::RBRACE) { + alt (p.peek()) { + case (token.WITH) { + p.bump(); + with_obj = some[ast::ident](parse_ident(p)); + } + case (_) { + Vec.push[@ast::method](meths, + parse_method(p)); + } + } + } + hi = p.get_hi_pos(); expect(p, token::LPAREN); - fields = some[vec[ast.obj_field]] - (parse_seq_to_end[ast.obj_field] + fields = some[vec[ast::obj_field]] + (parse_seq_to_end[ast::obj_field] (token::RPAREN, some(token::COMMA), pf, hi, p)); } - let vec[@ast.method] meths = vec(); - let option.t[ast.ident] with_obj = none[ast.ident]; + 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) { alt (p.peek()) { case (token::WITH) { - with_obj = some[ast.ident](parse_ident(p)); + with_obj = some[ast::ident](parse_ident(p)); } case (_) { // fall through @@ -841,13 +855,13 @@ fn parse_bottom_expr(parser p) -> @ast::expr { // We don't need to pull ".node" out of fields because it's not a // "spanned". - let ast.anon_obj ob = rec(fields=fields, + let ast::anon_obj ob = rec(fields=fields, methods=meths, with_obj=with_obj); 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); + 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); diff --git a/src/comp/middle/walk.rs b/src/comp/middle/walk.rs index 8a3c72f43e431..8dbcca0783cf0 100644 --- a/src/comp/middle/walk.rs +++ b/src/comp/middle/walk.rs @@ -433,6 +433,8 @@ fn walk_expr(&ast_visitor v, @ast::expr e) { case (ast::expr_chan(?x, _)) { walk_expr(v, x); } + + case (ast.expr_anon_obj(_,_,_,_)) { } } v.visit_expr_post(e); } diff --git a/src/test/run-pass/method-overriding.rs b/src/test/run-pass/method-overriding.rs index 3fbb53ff6cfd7..c76123fe7e175 100644 --- a/src/test/run-pass/method-overriding.rs +++ b/src/test/run-pass/method-overriding.rs @@ -24,7 +24,7 @@ fn main() { }; // Extending an object with a new field - auto my_c = obj(quux) { with my_a } ; + auto my_c = obj(int quux) { with my_a } ; // Should this be legal? auto my_d = obj() { with my_a } ; From 06c85416beb5e04f619b2dd3261cf7a02d5974bd Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Wed, 11 May 2011 16:41:25 -0700 Subject: [PATCH 5/8] More work toward anonymous objects. --- src/comp/middle/ty.rs | 1 - src/comp/middle/typeck.rs | 15 +++++++++------ src/comp/middle/walk.rs | 2 +- src/comp/pretty/pprust.rs | 5 +++++ 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 31d6b2c888ed3..86b53a9a04bb0 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1675,7 +1675,6 @@ 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; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 4a8f597471642..d926cc4b13b3e 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -2540,20 +2540,23 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto t = ty::mk_nil(fcx.ccx.tcx); let ty::t this_obj_ty; - // Grab the type of the current object auto this_obj_id = fcx.ccx.this_obj; alt (this_obj_id) { + // If we're inside a current object, grab its type. case (some[ast::def_id](?def_id)) { this_obj_ty = ty::lookup_item_type(fcx.ccx.sess, fcx.ccx.tcx, fcx.ccx.type_cache, def_id)._1; } - case (_) { fail; } + // Otherwise, we should be able to look up the object we're + // "with". + case (_) { + // TODO. + + fail; + } } - - // Grab this method's type out of the current object type - - // this_obj_ty is an ty::t + // Grab this method's type out of the current object type. alt (struct(fcx.ccx.tcx, this_obj_ty)) { case (ty::ty_obj(?methods)) { for (ty::method method in methods) { diff --git a/src/comp/middle/walk.rs b/src/comp/middle/walk.rs index 8dbcca0783cf0..fbf3060e96801 100644 --- a/src/comp/middle/walk.rs +++ b/src/comp/middle/walk.rs @@ -434,7 +434,7 @@ fn walk_expr(&ast_visitor v, @ast::expr e) { walk_expr(v, x); } - case (ast.expr_anon_obj(_,_,_,_)) { } + case (ast::expr_anon_obj(_,_,_,_)) { } } v.visit_expr_post(e); } diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index 0bdd5c8379fa0..c7c4fba36d3d0 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -690,6 +690,11 @@ fn print_expr(ps s, &@ast::expr expr) { print_expr(s, expr); pclose(s); } + + case (ast::expr_anon_obj(_,_,_,_)) { + wrd(s.s, "obj"); + // TODO + } } end(s.s); } From 5d7564ac21d04ed16dc16c70487b9acddde57ae4 Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Fri, 13 May 2011 11:00:26 -0700 Subject: [PATCH 6/8] Use new module namespace syntax. --- src/comp/front/ast.rs | 4 +- src/comp/front/parser.rs | 94 ++++++++++++++++++---------------------- src/comp/middle/fold.rs | 60 ++++++++++++------------- src/comp/middle/trans.rs | 2 +- 4 files changed, 76 insertions(+), 84 deletions(-) diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index eda09276184ce..d795d6c236324 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -374,10 +374,10 @@ type _obj = rec(vec[obj_field] fields, type anon_obj = rec( // New fields and methods, if they exist. - Option.t[vec[obj_field]] fields, + option::t[vec[obj_field]] fields, vec[@method] methods, // with_obj: the original object being extended, if it exists. - Option.t[ident] with_obj); + option::t[ident] with_obj); type _mod = rec(vec[@view_item] view_items, vec[@item] items); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index a02a2fa4b0b81..8eb6c398f9c98 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -773,58 +773,21 @@ fn parse_bottom_expr(parser p) -> @ast::expr { some(token::COMMA), pf, hi, p); ex = ast::expr_vec(es, mut, p.get_ann()); - } else if (eat_word(p, "rec")) { - expect(p, token::LPAREN); - auto fields = vec(parse_field(p)); - - auto more = true; - auto base = none[@ast::expr]; - while (more) { - if (p.peek() == token::RPAREN) { - hi = p.get_hi_pos(); - p.bump(); - more = false; - } else if (eat_word(p, "with")) { - base = some[@ast::expr](parse_expr(p)); - hi = p.get_hi_pos(); - expect(p, token::RPAREN); - more = false; - } else if (p.peek() == token::COMMA) { - p.bump(); - fields += vec(parse_field(p)); - } else { - unexpected(p, p.peek()); - } - } - - ex = ast::expr_rec(fields, base, p.get_ann()); - } - // Anonymous object - else if (eat_word(p, "obj")) { + } else if (eat_word(p, "obj")) { + // Anonymous object // FIXME: Can anonymous objects have ty params? auto ty_params = parse_ty_params(p); // Only make people type () if they're actually adding new fields - let option.t[vec[ast::obj_field]] fields = none[vec[ast::obj_field]]; + let option::t[vec[ast::obj_field]] fields = + none[vec[ast::obj_field]]; if (p.peek() == token::LPAREN) { auto pf = parse_obj_field; - expect(p, token::LBRACE); - while (p.peek() != token::RBRACE) { - alt (p.peek()) { - case (token.WITH) { - p.bump(); - with_obj = some[ast::ident](parse_ident(p)); - } - case (_) { - Vec.push[@ast::method](meths, - parse_method(p)); - } - } - } - hi = p.get_hi_pos(); expect(p, token::LPAREN); + + fields = some[vec[ast::obj_field]] (parse_seq_to_end[ast::obj_field] (token::RPAREN, @@ -833,36 +796,65 @@ fn parse_bottom_expr(parser p) -> @ast::expr { } let vec[@ast::method] meths = vec(); - let option.t[ast::ident] with_obj = none[ast::ident]; + let option::t[ast::ident] with_obj = none[ast::ident]; expect(p, token::LBRACE); + while (p.peek() != token::RBRACE) { alt (p.peek()) { case (token::WITH) { + p.bump(); with_obj = some[ast::ident](parse_ident(p)); } case (_) { - // fall through + _vec::push[@ast::method](meths, + parse_method(p)); } } } + hi = p.get_hi_pos(); 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 - // methods if there's no with_obj. + // 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 methods if there's no with_obj. // We don't need to pull ".node" out of fields because it's not a // "spanned". let ast::anon_obj ob = rec(fields=fields, - methods=meths, - with_obj=with_obj); + methods=meths, + with_obj=with_obj); 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); + ex = ast::expr_anon_obj(ob, ty_params, odid, p.get_ann()); + + } else if (eat_word(p, "rec")) { + expect(p, token::LPAREN); + auto fields = vec(parse_field(p)); + + auto more = true; + auto base = none[@ast::expr]; + while (more) { + if (p.peek() == token::RPAREN) { + hi = p.get_hi_pos(); + p.bump(); + more = false; + } else if (eat_word(p, "with")) { + base = some[@ast::expr](parse_expr(p)); + hi = p.get_hi_pos(); + expect(p, token::RPAREN); + more = false; + } else if (p.peek() == token::COMMA) { + p.bump(); + fields += vec(parse_field(p)); + } else { + unexpected(p, p.peek()); + } + } + ex = ast::expr_rec(fields, base, p.get_ann()); } 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 7d0fa9946a0e8..bd5f93f94d643 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -210,9 +210,9 @@ type ast_fold[ENV] = &@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, + &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, @@ -327,9 +327,9 @@ type ast_fold[ENV] = -> 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, + 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, @@ -838,7 +838,7 @@ fn fold_expr[ENV](&ENV env, &ast_fold[ENV] fld, &@expr e) -> @expr { ret fld.fold_expr_chan(env_, e.span, ee, t2); } - case (ast.expr_anon_obj(?ob, ?tps, ?odid, ?t)) { + 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); @@ -976,45 +976,45 @@ 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 { +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]]; + 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) { + 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]; + 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); + 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. + 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, + 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)); + _vec::push[@ast::method](meths, fold_method(_env, fld, m)); } ret fld.fold_anon_obj(env, fields, meths, with_obj); } @@ -1468,9 +1468,9 @@ fn identity_fold_expr_chan[ENV](&ENV e, &span sp, &@expr x, } 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)); + &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. @@ -1648,9 +1648,9 @@ fn identity_fold_obj[ENV](&ENV e, } 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 { + 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); } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index fa50d857ae908..fdc32f1108e15 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2889,7 +2889,7 @@ fn iter_sequence(@block_ctxt cx, cx.fcx.lcx.ccx.sess.bug("unexpected type in " + "trans::iter_sequence: " + - ty.ty_to_str(cx.fcx.lcx.ccx.tcx, t)); + ty::ty_to_str(cx.fcx.lcx.ccx.tcx, t)); fail; } } From 729404a7a043343c1d0fd7627856ca08830bfab2 Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Fri, 13 May 2011 16:35:22 -0700 Subject: [PATCH 7/8] More anon obj work; whitespace police in middle::fold Passing args to middle::fold::fold_expr_anon_obj by reference to be consistent with the other folds; adding a dummy fold_expr_anon_obj to typeck to be filled in later. --- src/comp/middle/fold.rs | 70 ++++++++++++++++++++++----------------- src/comp/middle/typeck.rs | 14 +++++++- 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index bd5f93f94d643..7a9a67ddfcaef 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -39,7 +39,8 @@ type ast_fold[ENV] = @rec ( // Path fold: - (fn(&ENV e, &span sp, &ast::path_ p) -> path) fold_path, + (fn(&ENV e, &span sp, &ast::path_ p) + -> path) fold_path, // Type folds. (fn(&ENV e, &span sp) -> @ty) fold_ty_nil, @@ -56,10 +57,10 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, &vec[mt] elts) -> @ty) fold_ty_tup, (fn(&ENV e, &span sp, - &vec[ast::ty_field] elts) -> @ty) fold_ty_rec, + &vec[ast::ty_field] elts) -> @ty) fold_ty_rec, (fn(&ENV e, &span sp, - &vec[ast::ty_method] meths) -> @ty) fold_ty_obj, + &vec[ast::ty_method] meths) -> @ty) fold_ty_obj, (fn(&ENV e, &span sp, ast::proto proto, @@ -78,7 +79,7 @@ type ast_fold[ENV] = &ann a) -> @expr) fold_expr_vec, (fn(&ENV e, &span sp, - &vec[ast::elt] es, &ann a) -> @expr) fold_expr_tup, + &vec[ast::elt] es, &ann a) -> @expr) fold_expr_tup, (fn(&ENV e, &span sp, &vec[ast::field] fields, @@ -110,7 +111,7 @@ type ast_fold[ENV] = &ann a) -> @expr) fold_expr_unary, (fn(&ENV e, &span sp, - &@ast::lit, &ann a) -> @expr) fold_expr_lit, + &@ast::lit, &ann a) -> @expr) fold_expr_lit, (fn(&ENV e, &span sp, &@ast::expr e, &@ast::ty ty, @@ -186,10 +187,10 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, &ann a) -> @expr) fold_expr_cont, (fn(&ENV e, &span sp, - &option::t[@expr] rv, &ann a) -> @expr) fold_expr_ret, + &option::t[@expr] rv, &ann a) -> @expr) fold_expr_ret, (fn(&ENV e, &span sp, - &option::t[@expr] rv, &ann a) -> @expr) fold_expr_put, + &option::t[@expr] rv, &ann a) -> @expr) fold_expr_put, (fn(&ENV e, &span sp, &@expr e, &ann a) -> @expr) fold_expr_be, @@ -210,13 +211,14 @@ type ast_fold[ENV] = &@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, + &ast::anon_obj ob, + &vec[ast::ty_param] tps, + &ast::obj_def_ids odid, + &ann a) -> @expr) fold_expr_anon_obj, // Decl folds. (fn(&ENV e, &span sp, - &@ast::local local) -> @decl) fold_decl_local, + &@ast::local local) -> @decl) fold_decl_local, (fn(&ENV e, &span sp, &@item item) -> @decl) fold_decl_item, @@ -227,7 +229,7 @@ type ast_fold[ENV] = &ann a) -> @pat) fold_pat_wild, (fn(&ENV e, &span sp, - &@ast::lit lit, &ann a) -> @pat) fold_pat_lit, + &@ast::lit lit, &ann a) -> @pat) fold_pat_lit, (fn(&ENV e, &span sp, &ident i, &def_id did, &ann a) -> @pat) fold_pat_bind, @@ -263,10 +265,11 @@ type ast_fold[ENV] = &def_id id, &ann a) -> @native_item) fold_native_item_fn, (fn(&ENV e, &span sp, &ident ident, - &ast::_mod m, &def_id id) -> @item) fold_item_mod, + &ast::_mod m, &def_id id) -> @item) fold_item_mod, (fn(&ENV e, &span sp, &ident ident, - &ast::native_mod m, &def_id id) -> @item) fold_item_native_mod, + &ast::native_mod m, &def_id id) + -> @item) fold_item_native_mod, (fn(&ENV e, &span sp, &ident ident, &@ty t, &vec[ast::ty_param] ty_params, @@ -283,13 +286,14 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, &ident ident, &ast::_obj ob, &vec[ast::ty_param] ty_params, - &ast::obj_def_ids odid, &ann a) -> @item) fold_item_obj, + &ast::obj_def_ids odid, &ann a) + -> @item) fold_item_obj, // View Item folds. (fn(&ENV e, &span sp, &ident ident, &vec[@meta_item] meta_items, &def_id id, - &option::t[int]) -> @view_item) fold_view_item_use, + &option::t[int]) -> @view_item) fold_view_item_use, (fn(&ENV e, &span sp, &ident i, &vec[ident] idents, @@ -305,31 +309,33 @@ type ast_fold[ENV] = (fn(&ENV e, &fn_decl decl, ast::proto proto, - &block body) -> ast::_fn) fold_fn, + &block body) -> ast::_fn) fold_fn, (fn(&ENV e, &vec[arg] inputs, &@ty output, - &purity p) -> ast::fn_decl) fold_fn_decl, + &purity p) -> ast::fn_decl) fold_fn_decl, - (fn(&ENV e, &ast::_mod m) -> ast::_mod) fold_mod, + (fn(&ENV e, &ast::_mod m) -> ast::_mod) fold_mod, - (fn(&ENV e, &ast::native_mod m) -> ast::native_mod) fold_native_mod, + (fn(&ENV e, &ast::native_mod m) + -> ast::native_mod) fold_native_mod, (fn(&ENV e, &span sp, &vec[@ast::crate_directive] cdirs, - &ast::_mod m) -> @ast::crate) fold_crate, + &ast::_mod m) -> @ast::crate) fold_crate, (fn(&ENV e, &vec[ast::obj_field] fields, &vec[@ast::method] methods, &option::t[@ast::method] dtor) - -> ast::_obj) fold_obj, + -> 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, + &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, @@ -976,7 +982,7 @@ 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) +fn fold_anon_obj[ENV](&ENV env, &ast_fold[ENV] fld, &ast::anon_obj ob) -> ast::anon_obj { // Fields @@ -1468,8 +1474,10 @@ fn identity_fold_expr_chan[ENV](&ENV e, &span sp, &@expr x, } 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 { + &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)); } @@ -1648,9 +1656,9 @@ fn identity_fold_obj[ENV](&ENV e, } 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 { + &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); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index d926cc4b13b3e..d5938b7bc6bc7 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -762,7 +762,18 @@ mod Collect { } } } + + // Anonymous objects are expressions, not items, but they're enough like + // items that we're going to include them in this fold. + fn fold_expr_anon_obj(&@env e, &span sp, + &ast::anon_obj ob, &vec[ast::ty_param] tps, + &ast::obj_def_ids odid, &ast::ann a) -> @ast::expr { + // TODO: Somewhere in here we need to push some stuff onto a vector. + + auto expr_anon_obj = ast::expr_anon_obj(ob, tps, odid, a); + ret @fold::respan[ast::expr_](sp, expr_anon_obj); + } fn fold_item_obj(&@env e, &span sp, &ast::ident i, &ast::_obj ob, &vec[ast::ty_param] ty_params, @@ -895,7 +906,8 @@ mod Collect { bind fold_native_item_fn(_,_,_,_,_,_,_,_), fold_item_obj = bind fold_item_obj(_,_,_,_,_,_,_), fold_item_ty = bind fold_item_ty(_,_,_,_,_,_,_), - fold_item_tag = bind fold_item_tag(_,_,_,_,_,_,_) + fold_item_tag = bind fold_item_tag(_,_,_,_,_,_,_), + fold_expr_anon_obj = bind fold_expr_anon_obj(_,_,_,_,_,_) with *fld_2); auto crate_ = fold::fold_crate[@env](e, fld_2, crate); ret tup(crate_, type_cache, id_to_ty_item, ntt); From dc93ffac684b0dfb0b2dd76a3abb959b14784071 Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Fri, 13 May 2011 17:26:14 -0700 Subject: [PATCH 8/8] 'with' no longer a token; whitespace police. Plus renaming the anonymous objects test to a more descriptive name, and XFAILing it because it doesn't work yet. --- src/comp/front/parser.rs | 14 +++++--------- src/comp/middle/typeck.rs | 3 ++- .../{method-overriding.rs => anon-objs.rs} | 1 + 3 files changed, 8 insertions(+), 10 deletions(-) rename src/test/run-pass/{method-overriding.rs => anon-objs.rs} (97%) diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 8eb6c398f9c98..767e7e932f179 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -801,15 +801,11 @@ fn parse_bottom_expr(parser p) -> @ast::expr { expect(p, token::LBRACE); while (p.peek() != token::RBRACE) { - alt (p.peek()) { - case (token::WITH) { - p.bump(); - with_obj = some[ast::ident](parse_ident(p)); - } - case (_) { - _vec::push[@ast::method](meths, - parse_method(p)); - } + if (eat_word(p, "with")) { + with_obj = some[ast::ident](parse_ident(p)); + } else { + _vec::push[@ast::method](meths, + parse_method(p)); } } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index d5938b7bc6bc7..c94e077d31fb4 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -2091,7 +2091,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) -> @ast::expr { auto e = ast::expr_path(pth, triv_ann(ast::ann_tag(old_ann), tpt._1)); - write_type_only(fcx.ccx.node_types, ast::ann_tag(old_ann), tpt._1); + write_type_only(fcx.ccx.node_types, + ast::ann_tag(old_ann), tpt._1); ret @fold::respan[ast::expr_](expr.span, e); } diff --git a/src/test/run-pass/method-overriding.rs b/src/test/run-pass/anon-objs.rs similarity index 97% rename from src/test/run-pass/method-overriding.rs rename to src/test/run-pass/anon-objs.rs index c76123fe7e175..14279db2e58cd 100644 --- a/src/test/run-pass/method-overriding.rs +++ b/src/test/run-pass/anon-objs.rs @@ -1,5 +1,6 @@ // xfail-boot // xfail-stage0 +// xfail-stage1 use std; fn main() {