Skip to content

Commit 367aae3

Browse files
lkupergraydon
authored andcommitted
---
yaml --- r: 2689 b: refs/heads/master c: c3410bf h: refs/heads/master i: 2687: ce531ef v: v3
1 parent a812063 commit 367aae3

File tree

16 files changed

+300
-46
lines changed

16 files changed

+300
-46
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 5de9d27fccb7ccfe0b22ea88633d65c3f019fe28
2+
refs/heads/master: c3410bf927c863cd33057184e97e6a6169475059

trunk/src/comp/back/abi.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ const int obj_field_box = 1;
5555
const int obj_body_elt_tydesc = 0;
5656
const int obj_body_elt_typarams = 1;
5757
const int obj_body_elt_fields = 2;
58+
const int obj_body_elt_with_obj = 3; /* The base object to which an anonymous
59+
* object is attached */
5860

5961
const int fn_field_code = 0;
6062
const int fn_field_box = 1;

trunk/src/comp/driver/session.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ state obj session(ast::crate_num cnum,
7979
ret cnum;
8080
}
8181

82-
fn span_err(span sp, str msg) -> ! {
82+
fn span_err(span sp, str msg) {
8383
// FIXME: Use constants, but rustboot doesn't know how to export them.
8484
emit_diagnostic(sp, msg, "error", 9u8, cm);
8585
fail;
8686
}
8787

88-
fn err(str msg) -> ! {
88+
fn err(str msg) {
8989
log_err #fmt("error: %s", msg);
9090
fail;
9191
}
@@ -107,19 +107,19 @@ state obj session(ast::crate_num cnum,
107107
emit_diagnostic(sp, msg, "note", 10u8, cm);
108108
}
109109

110-
fn bug(str msg) -> ! {
110+
fn bug(str msg) {
111111
log_err #fmt("error: internal compiler error %s", msg);
112112
fail;
113113
}
114114

115-
fn span_unimpl(span sp, str msg) -> ! {
115+
fn span_unimpl(span sp, str msg) {
116116
// FIXME: Use constants, but rustboot doesn't know how to export them.
117117
emit_diagnostic(sp, "internal compiler error: unimplemented " + msg,
118118
"error", 9u8, cm);
119119
fail;
120120
}
121-
122-
fn unimpl(str msg) -> ! {
121+
122+
fn unimpl(str msg) {
123123
log_err #fmt("error: unimplemented %s", msg);
124124
fail;
125125
}

trunk/src/comp/front/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ type anon_obj = rec(
379379
option::t[vec[obj_field]] fields,
380380
vec[@method] methods,
381381
// with_obj: the original object being extended, if it exists.
382-
option::t[ident] with_obj);
382+
option::t[@expr] with_obj);
383383

384384
type _mod = rec(vec[@view_item] view_items,
385385
vec[@item] items);

trunk/src/comp/front/parser.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ state type parser =
3131
state obj {
3232
fn peek() -> token::token;
3333
fn bump();
34-
fn err(str s) -> !;
34+
fn err(str s);
3535
fn restrict(restriction r);
3636
fn get_restriction() -> restriction;
3737
fn get_file_type() -> file_type;
@@ -85,7 +85,7 @@ fn new_parser(session::session sess,
8585
hi = rdr.get_chpos();
8686
}
8787

88-
fn err(str m) -> ! {
88+
fn err(str m) {
8989
sess.span_err(rec(lo=lo, hi=hi), m);
9090
}
9191

@@ -217,7 +217,7 @@ fn bad_expr_word_table() -> std::map::hashmap[str, ()] {
217217
ret words;
218218
}
219219

220-
fn unexpected(&parser p, token::token t) -> ! {
220+
fn unexpected(&parser p, token::token t) {
221221
let str s = "unexpected token: ";
222222
s += token::to_str(p.get_reader(), t);
223223
p.err(s);
@@ -820,13 +820,13 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
820820
}
821821

822822
let vec[@ast::method] meths = [];
823-
let option::t[ast::ident] with_obj = none[ast::ident];
823+
let option::t[@ast::expr] with_obj = none[@ast::expr];
824824

825825
expect(p, token::LBRACE);
826826

827827
while (p.peek() != token::RBRACE) {
828828
if (eat_word(p, "with")) {
829-
with_obj = some[ast::ident](parse_ident(p));
829+
with_obj = some[@ast::expr](parse_expr(p));
830830
} else {
831831
vec::push[@ast::method](meths,
832832
parse_method(p));

trunk/src/comp/middle/fold.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ type ast_fold[ENV] =
336336
(fn(&ENV e,
337337
&option::t[vec[ast::obj_field]] fields,
338338
&vec[@ast::method] methods,
339-
&option::t[ident] with_obj)
339+
&option::t[@ast::expr] with_obj)
340340
-> ast::anon_obj) fold_anon_obj,
341341

342342
// Env updates.
@@ -1001,11 +1001,11 @@ fn fold_anon_obj[ENV](&ENV env, &ast_fold[ENV] fld, &ast::anon_obj ob)
10011001
}
10021002

10031003
// with_obj
1004-
let option::t[ast::ident] with_obj = none[ast::ident];
1004+
let option::t[@ast::expr] with_obj = none[@ast::expr];
10051005
alt (ob.with_obj) {
1006-
case (none[ast::ident]) { }
1007-
case (some[ast::ident](?i)) {
1008-
with_obj = some[ast::ident](i);
1006+
case (none[@ast::expr]) { }
1007+
case (some[@ast::expr](?e)) {
1008+
with_obj = some[@ast::expr](fold_expr(env, fld, e));
10091009
}
10101010
}
10111011

@@ -1665,7 +1665,8 @@ fn identity_fold_obj[ENV](&ENV e,
16651665
fn identity_fold_anon_obj[ENV](&ENV e,
16661666
&option::t[vec[ast::obj_field]] fields,
16671667
&vec[@ast::method] methods,
1668-
&option::t[ident] with_obj) -> ast::anon_obj {
1668+
&option::t[@ast::expr] with_obj)
1669+
-> ast::anon_obj {
16691670
ret rec(fields=fields, methods=methods, with_obj=with_obj);
16701671
}
16711672

trunk/src/comp/middle/trans.rs

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4576,7 +4576,8 @@ fn trans_lval(&@block_ctxt cx, &@ast::expr e) -> lval_result {
45764576
}
45774577
case (_) {
45784578
cx.fcx.lcx.ccx.sess.span_unimpl(e.span,
4579-
"expr variant in trans_lval");
4579+
"expr variant in trans_lval: "
4580+
+ util::common::expr_to_str(e));
45804581
}
45814582
}
45824583
fail;
@@ -5547,6 +5548,10 @@ fn trans_expr(&@block_ctxt cx, &@ast::expr e) -> result {
55475548
ret trans_spawn(cx, dom, name, func, args, ann);
55485549
}
55495550

5551+
case (ast::expr_anon_obj(?anon_obj, ?tps, ?odid, ?ann)) {
5552+
ret trans_anon_obj(cx, e.span, anon_obj, tps, odid, ann);
5553+
}
5554+
55505555
case (_) {
55515556
// The expression is an lvalue. Fall through.
55525557
}
@@ -6111,6 +6116,77 @@ fn recv_val(&@block_ctxt cx, ValueRef lhs, &@ast::expr rhs,
61116116
ret res(bcx, lhs);
61126117
}
61136118

6119+
6120+
/*
6121+
6122+
Suppose we create an anonymous object my_b from a regular object a:
6123+
6124+
obj a() {
6125+
fn foo() -> int {
6126+
ret 2;
6127+
}
6128+
fn bar() -> int {
6129+
ret self.foo();
6130+
}
6131+
}
6132+
6133+
auto my_a = a();
6134+
auto my_b = obj { fn baz() -> int { ret self.foo() } with my_a };
6135+
6136+
Here we're extending the my_a object with an additional method baz, creating
6137+
an object my_b. Since it's an object, my_b is a pair of a vtable pointer and
6138+
a body pointer:
6139+
6140+
my_b: [vtbl* | body*]
6141+
6142+
my_b's vtable has entries for foo, bar, and baz, whereas my_a's vtable has
6143+
only foo and bar. my_b's 3-entry vtable consists of two forwarding functions
6144+
and one real method.
6145+
6146+
my_b's body just contains the pair a: [ a_vtable | a_body ], wrapped up with
6147+
any additional fields that my_b added. None were added, so my_b is just the
6148+
wrapped inner object.
6149+
6150+
*/
6151+
fn trans_anon_obj(&@block_ctxt cx, &ast::span sp,
6152+
&ast::anon_obj anon_obj,
6153+
&vec[ast::ty_param] ty_params,
6154+
&ast::obj_def_ids oid,
6155+
&ast::ann ann) -> result {
6156+
6157+
let option::t[result] with_obj_val = none[result];
6158+
alt (anon_obj.with_obj) {
6159+
case (none[@ast::expr]) { }
6160+
case (some[@ast::expr](?e)) {
6161+
// Translating with_obj returns a pointer to a 2-word value. We
6162+
// want to allocate space for this value in our outer object, then
6163+
// copy it into the outer object.
6164+
with_obj_val = some[result](trans_expr(cx, e));
6165+
}
6166+
}
6167+
6168+
// For the anon obj's additional fields, if any exist, translate object
6169+
// constructor arguments to function arguments.
6170+
let option::t[vec[ast::obj_field]] addtl_fields
6171+
= none[vec[ast::obj_field]];
6172+
let vec[ast::arg] addtl_fn_args = [];
6173+
6174+
alt (anon_obj.fields) {
6175+
case (none[vec[ast::obj_field]]) { }
6176+
case (some[vec[ast::obj_field]](?fields)) {
6177+
for (ast::obj_field f in fields) {
6178+
addtl_fn_args += [rec(mode=ast::alias, ty=f.ty,
6179+
ident=f.ident, id=f.id)];
6180+
}
6181+
}
6182+
}
6183+
6184+
// TODO: everything else.
6185+
6186+
cx.fcx.lcx.ccx.sess.unimpl("support for anonymous objects");
6187+
fail;
6188+
}
6189+
61146190
fn init_local(&@block_ctxt cx, &@ast::local local) -> result {
61156191

61166192
// Make a note to drop this slot on the way out.

trunk/src/comp/middle/tstate/ck.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,11 @@ fn check_states_against_conditions(&fn_ctxt fcx, &_fn f, &ann a) -> () {
129129
&& ! promises(*post, fcx.id, enclosing)
130130
&& ! type_is_nil(fcx.ccx.tcx,
131131
ret_ty_of_fn(fcx.ccx.tcx, a)) ) {
132-
fcx.ccx.tcx.sess.span_note(f.body.span, "In function " + fcx.name +
132+
/* FIXME: call span_err, not span_warn, once I finish implementing
133+
! annotations */
134+
fcx.ccx.tcx.sess.span_warn(f.body.span, "In function " + fcx.name +
133135
", not all control paths return a value");
134-
fcx.ccx.tcx.sess.span_err(f.decl.output.span,
136+
fcx.ccx.tcx.sess.span_note(f.decl.output.span,
135137
"see declared return type of '" + ty_to_str(*f.decl.output) +
136138
"'");
137139
}

trunk/src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ import front::ast::expr_assert;
132132
import front::ast::expr_cast;
133133
import front::ast::expr_for;
134134
import front::ast::expr_for_each;
135+
import front::ast::expr_anon_obj;
135136
import front::ast::stmt_decl;
136137
import front::ast::stmt_expr;
137138
import front::ast::block;
@@ -556,6 +557,17 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) -> () {
556557
find_pre_post_expr(fcx, expanded);
557558
copy_pre_post(fcx.ccx, a, expanded);
558559
}
560+
case (expr_anon_obj(?anon_obj, _, _, ?a)) {
561+
alt (anon_obj.with_obj) {
562+
case (some[@expr](?ex)) {
563+
find_pre_post_expr(fcx, ex);
564+
copy_pre_post(fcx.ccx, a, ex);
565+
}
566+
case (none[@expr]) {
567+
clear_pp(expr_pp(fcx.ccx, e));
568+
}
569+
}
570+
}
559571
}
560572
}
561573

trunk/src/comp/middle/tstate/states.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ import front::ast::expr_assert;
143143
import front::ast::expr_cast;
144144
import front::ast::expr_for;
145145
import front::ast::expr_for_each;
146+
import front::ast::expr_anon_obj;
146147
import front::ast::stmt_decl;
147148
import front::ast::stmt_expr;
148149
import front::ast::block;
@@ -578,6 +579,20 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
578579
case (expr_self_method(_, ?a)) {
579580
ret pure_exp(fcx.ccx, a, pres);
580581
}
582+
case (expr_anon_obj(?anon_obj, _, _,?a)) {
583+
alt (anon_obj.with_obj) {
584+
case (some[@expr](?e)) {
585+
changed = find_pre_post_state_expr(fcx, pres, e);
586+
changed = extend_prestate_ann(fcx.ccx, a, pres) || changed;
587+
changed = extend_poststate_ann(fcx.ccx, a,
588+
expr_poststate(fcx.ccx, e)) || changed;
589+
ret changed;
590+
}
591+
case (none[@expr]) {
592+
ret pure_exp(fcx.ccx, a, pres);
593+
}
594+
}
595+
}
581596
}
582597
}
583598

0 commit comments

Comments
 (0)