diff options
| author | Graydon Hoare <[email protected]> | 2011-04-14 16:50:48 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-04-14 16:50:59 -0700 |
| commit | 232c4509574bd27605dfa93890670e1ae1366e31 (patch) | |
| tree | fddaed0c44cb9b15355c20c37e00cec21d1d3df1 /src | |
| parent | rustc: Use the unified result for the type of assignment expressions (diff) | |
| download | rust-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.rs | 2 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 24 | ||||
| -rw-r--r-- | src/comp/middle/fold.rs | 12 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 37 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 16 | ||||
| -rw-r--r-- | src/comp/pretty/pprust.rs | 4 | ||||
| -rw-r--r-- | src/test/run-pass/obj-dtor-2.rs | 18 |
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 |