aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-04-14 16:50:48 -0700
committerGraydon Hoare <[email protected]>2011-04-14 16:50:59 -0700
commit232c4509574bd27605dfa93890670e1ae1366e31 (patch)
treefddaed0c44cb9b15355c20c37e00cec21d1d3df1 /src
parentrustc: Use the unified result for the type of assignment expressions (diff)
downloadrust-232c4509574bd27605dfa93890670e1ae1366e31.tar.xz
rust-232c4509574bd27605dfa93890670e1ae1366e31.zip
Work on destructors, not entirely functional yet (no tydesc integration).
Diffstat (limited to 'src')
-rw-r--r--src/comp/front/ast.rs2
-rw-r--r--src/comp/front/parser.rs24
-rw-r--r--src/comp/middle/fold.rs12
-rw-r--r--src/comp/middle/trans.rs37
-rw-r--r--src/comp/middle/typeck.rs16
-rw-r--r--src/comp/pretty/pprust.rs4
-rw-r--r--src/test/run-pass/obj-dtor-2.rs18
7 files changed, 100 insertions, 13 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index b0035ba6..b0a1a0d6 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -362,7 +362,7 @@ type method = spanned[method_];
type obj_field = rec(@ty ty, ident ident, def_id id, ann ann);
type _obj = rec(vec[obj_field] fields,
vec[@method] methods,
- option.t[block] dtor);
+ option.t[@method] dtor);
tag mod_index_entry {
mie_view_item(@view_item);
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index ab44f638..2e6e7c29 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -1823,6 +1823,25 @@ impure fn parse_method(parser p) -> @ast.method {
ret @spanned(lo, f.body.span.hi, meth);
}
+impure fn parse_dtor(parser p) -> @ast.method {
+ auto lo = p.get_lo_pos();
+ expect(p, token.DROP);
+ let ast.block b = parse_block(p);
+ let vec[ast.arg] inputs = vec();
+ let @ast.ty output = @spanned(lo, lo, ast.ty_nil);
+ let ast.fn_decl d = rec(effect=ast.eff_pure,
+ inputs=inputs,
+ output=output);
+ let ast._fn f = rec(decl = d,
+ proto = ast.proto_fn,
+ body = b);
+ let ast.method_ m = rec(ident="drop",
+ meth=f,
+ id=p.next_def_id(),
+ ann=ast.ann_none);
+ ret @spanned(lo, f.body.span.hi, m);
+}
+
impure fn parse_item_obj(parser p, ast.layer lyr) -> @ast.item {
auto lo = p.get_lo_pos();
expect(p, token.OBJ);
@@ -1837,14 +1856,13 @@ impure fn parse_item_obj(parser p, ast.layer lyr) -> @ast.item {
pf, p);
let vec[@ast.method] meths = vec();
- let option.t[ast.block] dtor = none[ast.block];
+ let option.t[@ast.method] dtor = none[@ast.method];
expect(p, token.LBRACE);
while (p.peek() != token.RBRACE) {
alt (p.peek()) {
case (token.DROP) {
- p.bump();
- dtor = some[ast.block](parse_block(p));
+ dtor = some[@ast.method](parse_dtor(p));
}
case (_) {
_vec.push[@ast.method](meths,
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index fbf43c55..3c141312 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -314,7 +314,7 @@ type ast_fold[ENV] =
(fn(&ENV e,
vec[ast.obj_field] fields,
vec[@ast.method] methods,
- option.t[block] dtor) -> ast._obj) fold_obj,
+ option.t[@ast.method] dtor) -> ast._obj) fold_obj,
// Env updates.
(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 {
for (ast.obj_field f in ob.fields) {
fields += vec(fold_obj_field(env, fld, f));
}
- let option.t[block] dtor = none[block];
+ let option.t[@ast.method] dtor = none[@ast.method];
alt (ob.dtor) {
- case (none[block]) { }
- case (some[block](?b)) {
- dtor = some[block](fold_block[ENV](env, fld, b));
+ case (none[@ast.method]) { }
+ case (some[@ast.method](?m)) {
+ dtor = some[@ast.method](fold_method[ENV](env, fld, m));
}
}
let vec[ast.ty_param] tp = vec();
@@ -1561,7 +1561,7 @@ fn identity_fold_crate[ENV](&ENV e, &span sp,
fn identity_fold_obj[ENV](&ENV e,
vec[ast.obj_field] fields,
vec[@ast.method] methods,
- option.t[block] dtor) -> ast._obj {
+ option.t[@ast.method] dtor) -> ast._obj {
ret rec(fields=fields, methods=methods, dtor=dtor);
}
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 13f37928..c5bb601b 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -5789,6 +5789,35 @@ fn trans_vtbl(@crate_ctxt cx,
ret gvar;
}
+fn trans_dtor(@crate_ctxt cx,
+ TypeRef llself_ty,
+ @ty.t self_ty,
+ &vec[ast.ty_param] ty_params,
+ &@ast.method dtor) -> ValueRef {
+
+ auto llfnty = T_nil();
+ alt (node_ann_type(cx, dtor.node.ann).struct) {
+ case (ty.ty_fn(?proto, ?inputs, ?output)) {
+ llfnty = type_of_fn_full(cx, proto,
+ some[TypeRef](llself_ty),
+ inputs, output,
+ _vec.len[ast.ty_param](ty_params));
+ }
+ }
+
+ let @crate_ctxt dcx = extend_path(cx, "drop");
+ let str s = mangle_name_by_seq(dcx, "drop");
+ let ValueRef llfn = decl_internal_fastcall_fn(cx.llmod, s, llfnty);
+ cx.item_ids.insert(dtor.node.id, llfn);
+ cx.item_symbols.insert(dtor.node.id, s);
+
+ trans_fn(dcx, dtor.node.meth, dtor.node.id,
+ some[tup(TypeRef, @ty.t)](tup(llself_ty, self_ty)),
+ ty_params, dtor.node.ann);
+
+ ret llfn;
+}
+
fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
&vec[ast.ty_param] ty_params, &ast.ann ann) {
@@ -5871,6 +5900,14 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
vec(0, abi.obj_body_elt_tydesc));
bcx = body_tydesc.bcx;
+ auto dtor = C_null(T_ptr(T_glue_fn(cx.tn)));
+ alt (ob.dtor) {
+ case (some[@ast.method](?d)) {
+ dtor = trans_dtor(cx, llself_ty, self_ty, ty_params, d);
+ }
+ case (none[@ast.method]) {}
+ }
+
auto body_td = get_tydesc(bcx, body_ty);
bcx = body_td.bcx;
bcx.build.Store(body_td.val, body_tydesc.val);
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 62825dd0..60b9178a 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -770,8 +770,22 @@ fn collect_item_types(session.session sess, @ast.crate crate)
_vec.push[ast.obj_field](fields, f);
}
+ auto dtor = none[@ast.method];
+ alt (ob.dtor) {
+ case (some[@ast.method](?d)) {
+ let vec[arg] inputs = vec();
+ let @ty.t output = @rec(struct=ty.ty_nil, cname=none[str]);
+ auto dtor_tfn = plain_ty(ty.ty_fn(ast.proto_fn,
+ inputs, output));
+ auto d_ = rec(ann=triv_ann(dtor_tfn) with d.node);
+ dtor = some[@ast.method](@rec(node=d_ with *d));
+ }
+ case (none[@ast.method]) { }
+ }
+
auto ob_ = rec(methods = methods,
- fields = fields
+ fields = fields,
+ dtor = dtor
with ob);
auto item = ast.item_obj(i, ob_, ty_params, odid, triv_ann(t));
ret @fold.respan[ast.item_](sp, item);
diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs
index c4c50845..e79e9eee 100644
--- a/src/comp/pretty/pprust.rs
+++ b/src/comp/pretty/pprust.rs
@@ -320,10 +320,10 @@ impure fn print_item(ps s, @ast.item item) {
line(s.s);
}
alt (_obj.dtor) {
- case (option.some[ast.block](?dtor)) {
+ case (option.some[@ast.method](?dtor)) {
hbox(s);
wrd1(s, "close");
- print_block(s, dtor);
+ print_block(s, dtor.node.meth.body);
end(s.s);
line(s.s);
}
diff --git a/src/test/run-pass/obj-dtor-2.rs b/src/test/run-pass/obj-dtor-2.rs
new file mode 100644
index 00000000..167b15fb
--- /dev/null
+++ b/src/test/run-pass/obj-dtor-2.rs
@@ -0,0 +1,18 @@
+// xfail-stage00
+
+obj foo(@mutable int x) {
+ drop {
+ log "running dtor";
+ *x = ((*x) + 1);
+ }
+}
+
+
+
+fn main() {
+ auto mbox = @mutable 10;
+ {
+ auto x = foo(mbox);
+ }
+ check ((*mbox) == 11);
+} \ No newline at end of file