Skip to content

Commit 232c450

Browse files
committed
Work on destructors, not entirely functional yet (no tydesc integration).
1 parent 0387b5a commit 232c450

File tree

7 files changed

+100
-13
lines changed

7 files changed

+100
-13
lines changed

src/comp/front/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ type method = spanned[method_];
362362
type obj_field = rec(@ty ty, ident ident, def_id id, ann ann);
363363
type _obj = rec(vec[obj_field] fields,
364364
vec[@method] methods,
365-
option.t[block] dtor);
365+
option.t[@method] dtor);
366366
367367
tag mod_index_entry {
368368
mie_view_item(@view_item);

src/comp/front/parser.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,6 +1823,25 @@ impure fn parse_method(parser p) -> @ast.method {
18231823
ret @spanned(lo, f.body.span.hi, meth);
18241824
}
18251825

1826+
impure fn parse_dtor(parser p) -> @ast.method {
1827+
auto lo = p.get_lo_pos();
1828+
expect(p, token.DROP);
1829+
let ast.block b = parse_block(p);
1830+
let vec[ast.arg] inputs = vec();
1831+
let @ast.ty output = @spanned(lo, lo, ast.ty_nil);
1832+
let ast.fn_decl d = rec(effect=ast.eff_pure,
1833+
inputs=inputs,
1834+
output=output);
1835+
let ast._fn f = rec(decl = d,
1836+
proto = ast.proto_fn,
1837+
body = b);
1838+
let ast.method_ m = rec(ident="drop",
1839+
meth=f,
1840+
id=p.next_def_id(),
1841+
ann=ast.ann_none);
1842+
ret @spanned(lo, f.body.span.hi, m);
1843+
}
1844+
18261845
impure fn parse_item_obj(parser p, ast.layer lyr) -> @ast.item {
18271846
auto lo = p.get_lo_pos();
18281847
expect(p, token.OBJ);
@@ -1837,14 +1856,13 @@ impure fn parse_item_obj(parser p, ast.layer lyr) -> @ast.item {
18371856
pf, p);
18381857

18391858
let vec[@ast.method] meths = vec();
1840-
let option.t[ast.block] dtor = none[ast.block];
1859+
let option.t[@ast.method] dtor = none[@ast.method];
18411860

18421861
expect(p, token.LBRACE);
18431862
while (p.peek() != token.RBRACE) {
18441863
alt (p.peek()) {
18451864
case (token.DROP) {
1846-
p.bump();
1847-
dtor = some[ast.block](parse_block(p));
1865+
dtor = some[@ast.method](parse_dtor(p));
18481866
}
18491867
case (_) {
18501868
_vec.push[@ast.method](meths,

src/comp/middle/fold.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ type ast_fold[ENV] =
314314
(fn(&ENV e,
315315
vec[ast.obj_field] fields,
316316
vec[@ast.method] methods,
317-
option.t[block] dtor) -> ast._obj) fold_obj,
317+
option.t[@ast.method] dtor) -> ast._obj) fold_obj,
318318

319319
// Env updates.
320320
(fn(&ENV e, @ast.crate c) -> ENV) update_env_for_crate,
@@ -927,11 +927,11 @@ fn fold_obj[ENV](&ENV env, ast_fold[ENV] fld, &ast._obj ob) -> ast._obj {
927927
for (ast.obj_field f in ob.fields) {
928928
fields += vec(fold_obj_field(env, fld, f));
929929
}
930-
let option.t[block] dtor = none[block];
930+
let option.t[@ast.method] dtor = none[@ast.method];
931931
alt (ob.dtor) {
932-
case (none[block]) { }
933-
case (some[block](?b)) {
934-
dtor = some[block](fold_block[ENV](env, fld, b));
932+
case (none[@ast.method]) { }
933+
case (some[@ast.method](?m)) {
934+
dtor = some[@ast.method](fold_method[ENV](env, fld, m));
935935
}
936936
}
937937
let vec[ast.ty_param] tp = vec();
@@ -1561,7 +1561,7 @@ fn identity_fold_crate[ENV](&ENV e, &span sp,
15611561
fn identity_fold_obj[ENV](&ENV e,
15621562
vec[ast.obj_field] fields,
15631563
vec[@ast.method] methods,
1564-
option.t[block] dtor) -> ast._obj {
1564+
option.t[@ast.method] dtor) -> ast._obj {
15651565
ret rec(fields=fields, methods=methods, dtor=dtor);
15661566
}
15671567

src/comp/middle/trans.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5789,6 +5789,35 @@ fn trans_vtbl(@crate_ctxt cx,
57895789
ret gvar;
57905790
}
57915791

5792+
fn trans_dtor(@crate_ctxt cx,
5793+
TypeRef llself_ty,
5794+
@ty.t self_ty,
5795+
&vec[ast.ty_param] ty_params,
5796+
&@ast.method dtor) -> ValueRef {
5797+
5798+
auto llfnty = T_nil();
5799+
alt (node_ann_type(cx, dtor.node.ann).struct) {
5800+
case (ty.ty_fn(?proto, ?inputs, ?output)) {
5801+
llfnty = type_of_fn_full(cx, proto,
5802+
some[TypeRef](llself_ty),
5803+
inputs, output,
5804+
_vec.len[ast.ty_param](ty_params));
5805+
}
5806+
}
5807+
5808+
let @crate_ctxt dcx = extend_path(cx, "drop");
5809+
let str s = mangle_name_by_seq(dcx, "drop");
5810+
let ValueRef llfn = decl_internal_fastcall_fn(cx.llmod, s, llfnty);
5811+
cx.item_ids.insert(dtor.node.id, llfn);
5812+
cx.item_symbols.insert(dtor.node.id, s);
5813+
5814+
trans_fn(dcx, dtor.node.meth, dtor.node.id,
5815+
some[tup(TypeRef, @ty.t)](tup(llself_ty, self_ty)),
5816+
ty_params, dtor.node.ann);
5817+
5818+
ret llfn;
5819+
}
5820+
57925821
fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
57935822
&vec[ast.ty_param] ty_params, &ast.ann ann) {
57945823

@@ -5871,6 +5900,14 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
58715900
vec(0, abi.obj_body_elt_tydesc));
58725901
bcx = body_tydesc.bcx;
58735902

5903+
auto dtor = C_null(T_ptr(T_glue_fn(cx.tn)));
5904+
alt (ob.dtor) {
5905+
case (some[@ast.method](?d)) {
5906+
dtor = trans_dtor(cx, llself_ty, self_ty, ty_params, d);
5907+
}
5908+
case (none[@ast.method]) {}
5909+
}
5910+
58745911
auto body_td = get_tydesc(bcx, body_ty);
58755912
bcx = body_td.bcx;
58765913
bcx.build.Store(body_td.val, body_tydesc.val);

src/comp/middle/typeck.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,8 +770,22 @@ fn collect_item_types(session.session sess, @ast.crate crate)
770770
_vec.push[ast.obj_field](fields, f);
771771
}
772772

773+
auto dtor = none[@ast.method];
774+
alt (ob.dtor) {
775+
case (some[@ast.method](?d)) {
776+
let vec[arg] inputs = vec();
777+
let @ty.t output = @rec(struct=ty.ty_nil, cname=none[str]);
778+
auto dtor_tfn = plain_ty(ty.ty_fn(ast.proto_fn,
779+
inputs, output));
780+
auto d_ = rec(ann=triv_ann(dtor_tfn) with d.node);
781+
dtor = some[@ast.method](@rec(node=d_ with *d));
782+
}
783+
case (none[@ast.method]) { }
784+
}
785+
773786
auto ob_ = rec(methods = methods,
774-
fields = fields
787+
fields = fields,
788+
dtor = dtor
775789
with ob);
776790
auto item = ast.item_obj(i, ob_, ty_params, odid, triv_ann(t));
777791
ret @fold.respan[ast.item_](sp, item);

src/comp/pretty/pprust.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,10 @@ impure fn print_item(ps s, @ast.item item) {
320320
line(s.s);
321321
}
322322
alt (_obj.dtor) {
323-
case (option.some[ast.block](?dtor)) {
323+
case (option.some[@ast.method](?dtor)) {
324324
hbox(s);
325325
wrd1(s, "close");
326-
print_block(s, dtor);
326+
print_block(s, dtor.node.meth.body);
327327
end(s.s);
328328
line(s.s);
329329
}

src/test/run-pass/obj-dtor-2.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// xfail-stage00
2+
3+
obj foo(@mutable int x) {
4+
drop {
5+
log "running dtor";
6+
*x = ((*x) + 1);
7+
}
8+
}
9+
10+
11+
12+
fn main() {
13+
auto mbox = @mutable 10;
14+
{
15+
auto x = foo(mbox);
16+
}
17+
check ((*mbox) == 11);
18+
}

0 commit comments

Comments
 (0)