From 24102d50ad2335c1da5c10ddab8996534b2760dc Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 13 Jan 2012 10:58:31 +0100 Subject: [PATCH] Obj system? What obj system? Removes the obj system from the compiler. Closes #1484 --- src/comp/back/abi.rs | 15 +- src/comp/metadata/encoder.rs | 32 - src/comp/metadata/tydecode.rs | 18 - src/comp/metadata/tyencode.rs | 9 - src/comp/middle/alias.rs | 25 +- src/comp/middle/ast_map.rs | 29 - src/comp/middle/debuginfo.rs | 3 - src/comp/middle/gc.rs | 6 +- src/comp/middle/kind.rs | 4 +- src/comp/middle/mut.rs | 6 +- src/comp/middle/resolve.rs | 61 +- src/comp/middle/shape.rs | 39 +- src/comp/middle/trans.rs | 299 ++---- src/comp/middle/trans_closure.rs | 4 +- src/comp/middle/trans_common.rs | 41 +- src/comp/middle/trans_impl.rs | 12 +- src/comp/middle/trans_objects.rs | 951 ------------------ src/comp/middle/trans_vec.rs | 4 +- src/comp/middle/tstate/pre_post_conditions.rs | 10 - src/comp/middle/tstate/states.rs | 6 - src/comp/middle/ty.rs | 109 +- src/comp/middle/typeck.rs | 209 +--- src/comp/rustc.rc | 1 - src/comp/syntax/ast.rs | 24 +- src/comp/syntax/ast_util.rs | 6 +- src/comp/syntax/fold.rs | 38 - src/comp/syntax/parse/parser.rs | 84 +- src/comp/syntax/print/pprust.rs | 76 -- src/comp/syntax/visit.rs | 33 - src/comp/util/ppaux.rs | 5 - 30 files changed, 139 insertions(+), 2020 deletions(-) delete mode 100644 src/comp/middle/trans_objects.rs diff --git a/src/comp/back/abi.rs b/src/comp/back/abi.rs index 8e317ce0e9e5..9de31c2d014d 100644 --- a/src/comp/back/abi.rs +++ b/src/comp/back/abi.rs @@ -46,7 +46,7 @@ const tydesc_field_cmp_glue: int = 10; const tydesc_field_shape: int = 11; const tydesc_field_shape_tables: int = 12; const tydesc_field_n_params: int = 13; -const tydesc_field_obj_params: int = 14; +const tydesc_field_obj_params: int = 14; // FIXME unused const n_tydesc_fields: int = 15; const cmp_glue_op_eq: uint = 0u; @@ -55,19 +55,6 @@ const cmp_glue_op_lt: uint = 1u; const cmp_glue_op_le: uint = 2u; -const obj_field_vtbl: int = 0; - -const obj_field_box: int = 1; - -const obj_body_elt_tydesc: int = 0; - -const obj_body_elt_typarams: int = 1; - -const obj_body_elt_fields: int = 2; - -// The base object to which an anonymous object is attached. -const obj_body_elt_inner_obj: int = 3; - // The two halves of a closure: code and environment. const fn_field_code: int = 0; const fn_field_box: int = 1; diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index 37bc22e4931b..0e61fdfa123e 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -126,18 +126,6 @@ fn encode_module_item_paths(ebml_w: ebml::writer, module: _mod, path: [str], ebml::end_tag(ebml_w); encode_tag_variant_paths(ebml_w, variants, path, index); } - item_obj(_, tps, ctor_id) { - add_to_index(ebml_w, path, index, it.ident); - ebml::start_tag(ebml_w, tag_paths_data_item); - encode_name(ebml_w, it.ident); - encode_def_id(ebml_w, local_def(ctor_id)); - ebml::end_tag(ebml_w); - add_to_index(ebml_w, path, index, it.ident); - ebml::start_tag(ebml_w, tag_paths_data_item); - encode_name(ebml_w, it.ident); - encode_def_id(ebml_w, local_def(it.id)); - ebml::end_tag(ebml_w); - } item_iface(_, _) { add_to_index(ebml_w, path, index, it.ident); ebml::start_tag(ebml_w, tag_paths_data_item); @@ -366,26 +354,6 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_symbol(ecx, ebml_w, ctor_id); ebml::end_tag(ebml_w); } - item_obj(_, tps, ctor_id) { - let fn_ty = node_id_to_monotype(tcx, ctor_id); - - ebml::start_tag(ebml_w, tag_items_data_item); - encode_def_id(ebml_w, local_def(item.id)); - encode_family(ebml_w, 'y' as u8); - encode_type_param_bounds(ebml_w, ecx, tps); - encode_type(ecx, ebml_w, ty::ty_fn_ret(tcx, fn_ty)); - encode_name(ebml_w, item.ident); - ebml::end_tag(ebml_w); - - index += [{val: ctor_id, pos: ebml_w.writer.tell()}]; - ebml::start_tag(ebml_w, tag_items_data_item); - encode_def_id(ebml_w, local_def(ctor_id)); - encode_family(ebml_w, 'f' as u8); - encode_type_param_bounds(ebml_w, ecx, tps); - encode_type(ecx, ebml_w, fn_ty); - encode_symbol(ecx, ebml_w, ctor_id); - ebml::end_tag(ebml_w); - } item_impl(tps, ifce, _, methods) { ebml::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index caddce43f72a..8b5cbc5ff1aa 100644 --- a/src/comp/metadata/tydecode.rs +++ b/src/comp/metadata/tydecode.rs @@ -246,24 +246,6 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { let func = parse_ty_fn(st, conv); ret ty::mk_native_fn(st.tcx, func.inputs, func.output); } - 'O' { - assert (next(st) as char == '['); - let methods: [ty::method] = []; - while peek(st) as char != ']' { - let proto; - alt next(st) as char { - 'f' { proto = ast::proto_bare; } - } - let name = ""; - while peek(st) as char != '[' { - name += str::unsafe_from_byte(next(st)); - } - methods += [{ident: name, tps: @[], - fty: {proto: proto with parse_ty_fn(st, conv)}}]; - } - st.pos += 1u; - ret ty::mk_obj(st.tcx, methods); - } 'r' { assert (next(st) as char == '['); let def = parse_def(st, conv); diff --git a/src/comp/metadata/tyencode.rs b/src/comp/metadata/tyencode.rs index 83b69f0cad1a..4e75271c11d5 100644 --- a/src/comp/metadata/tyencode.rs +++ b/src/comp/metadata/tyencode.rs @@ -157,15 +157,6 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) { enc_ty_fn(w, cx, {proto: proto_bare, inputs: args, output: out, ret_style: return_val, constraints: []}); } - ty::ty_obj(methods) { - w.write_str("O["); - for m: ty::method in methods { - enc_proto(w, m.fty.proto); - w.write_str(m.ident); - enc_ty_fn(w, cx, m.fty); - } - w.write_char(']'); - } ty::ty_res(def, ty, tps) { w.write_str("r["); w.write_str(cx.ds(def)); diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index 82058a6a7814..ce887d301944 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -56,8 +56,8 @@ type ctx = {tcx: ty::ctxt, mutable silent: bool}; fn check_crate(tcx: ty::ctxt, crate: @ast::crate) -> (copy_map, ref_map) { - // Stores information about object fields and function - // arguments that's otherwise not easily available. + // Stores information about function arguments that's otherwise not easily + // available. let cx = @{tcx: tcx, copy_map: std::map::new_int_hash(), ref_map: std::map::new_int_hash(), @@ -521,7 +521,7 @@ fn ty_can_unsafely_include(cx: ctx, needle: unsafe_ty, haystack: ty::t, } ty::ty_fn({proto: ast::proto_bare., _}) { ret false; } // These may contain anything. - ty::ty_fn(_) | ty::ty_obj(_) { ret true; } + ty::ty_fn(_) | ty::ty_iface(_, _) { ret true; } // A type param may include everything, but can only be // treated as opaque downstream, and is thus safe unless we // saw mutable fields, in which case the whole thing can be @@ -536,8 +536,7 @@ fn ty_can_unsafely_include(cx: ctx, needle: unsafe_ty, haystack: ty::t, fn def_is_local(d: ast::def) -> bool { alt d { ast::def_local(_, _) | ast::def_arg(_, _) | ast::def_binding(_) | - ast::def_upvar(_, _, _) | ast::def_self(_) | - ast::def_obj_field(_, _) { true } + ast::def_upvar(_, _, _) | ast::def_self(_) { true } _ { false } } } @@ -557,10 +556,9 @@ fn copy_is_expensive(tcx: ty::ctxt, ty: ty::t) -> bool { ty::ty_nil. | ty::ty_bot. | ty::ty_bool. | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) | ty::ty_type. | ty::ty_native(_) | ty::ty_ptr(_) { 1u } - ty::ty_box(_) { 3u } + ty::ty_box(_) | ty::ty_iface(_, _) { 3u } ty::ty_constr(t, _) | ty::ty_res(_, t, _) { score_ty(tcx, t) } - ty::ty_fn(_) | ty::ty_native_fn(_, _) | - ty::ty_obj(_) { 4u } + ty::ty_fn(_) | ty::ty_native_fn(_, _) { 4u } ty::ty_str. | ty::ty_vec(_) | ty::ty_param(_, _) { 50u } ty::ty_uniq(mt) { 1u + score_ty(tcx, mt.ty) } ty::ty_tag(_, ts) | ty::ty_tup(ts) { @@ -633,17 +631,6 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool) for d in *base_root.ds { if d.mut { unsafe_ty = some(contains(d.outer_t)); break; } } - alt base_root.ex.node { - ast::expr_path(_) { - alt cx.tcx.def_map.get(base_root.ex.id) { - ast::def_obj_field(_, ast::mut.) { - unsafe_ty = some(mut_contains(ty::expr_ty(cx.tcx, base_root.ex))); - } - _ {} - } - } - _ {} - } ret {ex: base_root.ex, mut: unsafe_ty}; } diff --git a/src/comp/middle/ast_map.rs b/src/comp/middle/ast_map.rs index c9382589d73c..1af44c812098 100644 --- a/src/comp/middle/ast_map.rs +++ b/src/comp/middle/ast_map.rs @@ -6,8 +6,6 @@ import syntax::{visit, codemap}; tag ast_node { node_item(@item); - node_obj_ctor(@item); - node_obj_method(@method); node_native_item(@native_item); node_method(@method); node_expr(@expr); @@ -62,12 +60,6 @@ fn map_arm(cx: ctx, arm: arm) { fn map_item(cx: ctx, i: @item) { cx.map.insert(i.id, node_item(i)); alt i.node { - item_obj(ob, _, ctor_id) { - cx.map.insert(ctor_id, node_obj_ctor(i)); - for m in ob.methods { - cx.map.insert(m.id, node_obj_method(m)); - } - } item_impl(_, _, _, ms) { for m in ms { cx.map.insert(m.id, node_method(m)); } } @@ -85,20 +77,11 @@ fn map_native_item(cx: ctx, i: @native_item) { fn map_expr(cx: ctx, ex: @expr) { cx.map.insert(ex.id, node_expr(ex)); - alt ex.node { - expr_anon_obj(ao) { - for m in ao.methods { - cx.map.insert(m.id, node_obj_method(m)); - } - } - _ {} - } } fn node_span(node: ast_node) -> codemap::span { alt node { node_item(item) { item.span } - node_obj_ctor(item) { item.span } node_native_item(nitem) { nitem.span } node_expr(expr) { expr.span } } @@ -120,18 +103,6 @@ mod test { assert (node_span(node) == expected); } - #[test] - fn test_node_span_obj_ctor() { - let expected: codemap::span = ast_util::mk_sp(20u, 30u); - let node = - node_obj_ctor(@{ident: "test", - attrs: [], - id: 0, - node: item_mod({view_items: [], items: []}), - span: expected}); - assert (node_span(node) == expected); - } - #[test] fn test_node_span_native_item() { let expected: codemap::span = ast_util::mk_sp(20u, 30u); diff --git a/src/comp/middle/debuginfo.rs b/src/comp/middle/debuginfo.rs index fab7f625b0f8..540728e60224 100644 --- a/src/comp/middle/debuginfo.rs +++ b/src/comp/middle/debuginfo.rs @@ -727,9 +727,6 @@ fn create_function(fcx: @fn_ctxt) -> @metadata { } } } - ast_map::node_obj_method(method) | ast_map::node_method(method) { - (method.ident, method.decl.output, method.id) - } ast_map::node_res_ctor(item) { alt item.node { ast::item_res(decl, _, _, _, ctor_id) { (item.ident, decl.output, ctor_id) diff --git a/src/comp/middle/gc.rs b/src/comp/middle/gc.rs index 6860039aa9f7..ebd1d4ff9f4f 100644 --- a/src/comp/middle/gc.rs +++ b/src/comp/middle/gc.rs @@ -3,7 +3,7 @@ import lib::llvm::True; import lib::llvm::llvm::ValueRef; import middle::trans; -import middle::trans::{get_tydesc, tps_normal}; +import middle::trans::get_tydesc; import middle::trans_common::*; import middle::ty; import option::none; @@ -43,7 +43,7 @@ fn add_gc_root(cx: @block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt { bcx = trans::zero_alloca(bcx, llval, ty); let ti = none; - let td_r = get_tydesc(bcx, ty, false, tps_normal, ti); + let td_r = get_tydesc(bcx, ty, false, ti); bcx = td_r.result.bcx; let lltydesc = td_r.result.val; @@ -147,7 +147,7 @@ fn type_is_gc_relevant(cx: ty::ctxt, ty: ty::t) -> bool { } ty::ty_constr(sub, _) { ret type_is_gc_relevant(cx, sub); } ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_fn(_) | - ty::ty_native_fn(_, _) | ty::ty_obj(_) | ty::ty_param(_, _) | + ty::ty_native_fn(_, _) | ty::ty_param(_, _) | ty::ty_res(_, _, _) { ret true; } ty::ty_var(_) { fail "ty_var in type_is_gc_relevant"; diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs index c9659e7b60a8..51ab1ad3690b 100644 --- a/src/comp/middle/kind.rs +++ b/src/comp/middle/kind.rs @@ -8,7 +8,7 @@ import driver::session::session; // Kind analysis pass. There are three kinds: // // sendable: scalar types, and unique types containing only sendable types -// copyable: boxes, objects, closures, and uniques containing copyable types +// copyable: boxes, closures, and uniques containing copyable types // noncopyable: resources, or unique types containing resources // // This pass ensures that type parameters are only instantiated with types @@ -218,7 +218,7 @@ fn maybe_copy(cx: ctx, ex: @expr) { } fn check_copy_ex(cx: ctx, ex: @expr, _warn: bool) { - if ty::expr_is_lval(cx.method_map, cx.tcx, ex) && + if ty::expr_is_lval(cx.method_map, ex) && !cx.last_uses.contains_key(ex.id) { let ty = ty::expr_ty(cx.tcx, ex); check_copy(cx, ty, ex.span); diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs index 57dea65ce1ab..d67e8bf49496 100644 --- a/src/comp/middle/mut.rs +++ b/src/comp/middle/mut.rs @@ -60,7 +60,7 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) -> } } } - ty::ty_obj(_) { } + _ {} } ds += [@{mut: is_mut, kind: field, outer_t: auto_unbox.t}]; ds += auto_unbox.ds; @@ -201,9 +201,6 @@ fn check_move_rhs(cx: @ctx, src: @expr) { alt src.node { expr_path(p) { alt cx.tcx.def_map.get(src.id) { - def_obj_field(_, _) { - mk_err(cx, src.span, msg_move_out, "object field"); - } def_self(_) { mk_err(cx, src.span, msg_move_out, "method self"); } @@ -267,7 +264,6 @@ fn is_immutable_def(cx: @ctx, def: def) -> option::t { } def_arg(_, by_ref.) | def_arg(_, by_val.) | def_arg(_, mode_infer.) { some("argument") } - def_obj_field(_, imm.) { some("immutable object field") } def_self(_) { some("self argument") } def_upvar(_, inner, node_id) { let ty = ty::node_id_to_monotype(cx.tcx, node_id); diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 31fbfea9234b..b83588591cd2 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -535,9 +535,6 @@ fn visit_expr_with_scope(x: @ast::expr, sc: scopes, v: vt) { v.visit_local(decl, new_sc, v); v.visit_block(blk, new_sc, v); } - ast::expr_anon_obj(_) { - visit::visit_expr(x, cons(scope_method(x.id, []), @sc), v); - } _ { visit::visit_expr(x, sc, v); } } } @@ -852,9 +849,9 @@ fn def_is_local(d: def) -> bool { } } -fn def_has_obj_scope(d: def) -> bool { +fn def_is_self(d: def) -> bool { alt d { - ast::def_obj_field(_, _) | ast::def_self(_) { true } + ast::def_self(_) { true } _ { false } } } @@ -874,9 +871,6 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace) } scope_item(it) { alt it.node { - ast::item_obj(ob, ty_params, _) { - ret lookup_in_obj(e, name, ob, ty_params, ns, it.id); - } ast::item_impl(tps, _, _, _) { if ns == ns_type { ret lookup_in_ty_params(e, name, tps); } } @@ -935,7 +929,7 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace) } let left_fn = false; let closing = []; - // Used to determine whether obj fields are in scope + // Used to determine whether self is in scope let left_fn_level2 = false; let sc = sc; while true { @@ -945,9 +939,8 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace) let fnd = in_scope(e, sp, name, hd, ns); if !is_none(fnd) { let df = option::get(fnd); - let local = def_is_local(df), - obj_scope = def_has_obj_scope(df); - if left_fn && local || left_fn_level2 && obj_scope + let local = def_is_local(df), self_scope = def_is_self(df); + if left_fn && local || left_fn_level2 && self_scope || scope_is_fn(hd) && left_fn && def_is_ty_arg(df) { let msg = alt ns { ns_type. { @@ -965,7 +958,7 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace) _ { "attempted dynamic environment-capture" } }; e.sess.span_fatal(sp, msg); - } else if local || obj_scope { + } else if local || self_scope { let i = vec::len(closing); while i > 0u { i -= 1u; @@ -1030,24 +1023,6 @@ fn lookup_in_fn(e: env, name: ident, decl: ast::fn_decl, } } -fn lookup_in_obj(e: env, name: ident, ob: ast::_obj, - ty_params: [ast::ty_param], - ns: namespace, id: node_id) -> option::t { - alt ns { - ns_val(val_ty) { - if name == "self" && val_ty == ns_any_value - { ret some(ast::def_self(local_def(id))); } - for f: ast::obj_field in ob.fields { - if str::eq(f.ident, name) && val_ty == ns_any_value { - ret some(ast::def_obj_field(local_def(f.id), f.mut)); - } - } - ret none::; - } - ns_type. { ret lookup_in_ty_params(e, name, ty_params); } - _ { ret none::; } - } -} fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint, loc_pos: uint, ns: namespace) -> option::t { @@ -1166,15 +1141,6 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t { _ { } } } - ast::item_obj(_, _, ctor_id) { - alt ns { - ns_val(ns_any_value.) { - ret some(ast::def_fn(local_def(ctor_id), ast::impure_fn)); - } - ns_type. { ret some(ast::def_ty(local_def(i.id))); } - _ { } - } - } _ { } } ret none; @@ -1422,7 +1388,7 @@ fn index_mod(md: ast::_mod) -> mod_index { alt it.node { ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) | ast::item_native_mod(_) | ast::item_ty(_, _) | - ast::item_res(_, _, _, _, _) | ast::item_obj(_, _, _) | + ast::item_res(_, _, _, _, _) | ast::item_impl(_, _, _, _) | ast::item_iface(_, _) { add_to_index(index, it.ident, mie_item(it)); } @@ -1470,7 +1436,7 @@ fn index_nmod(md: ast::native_mod) -> mod_index { fn ns_for_def(d: def) -> namespace { alt d { ast::def_variant(_, _) { ns_val(ns_a_tag) } - ast::def_fn(_, _) | ast::def_obj_field(_, _) | ast::def_self(_) | + ast::def_fn(_, _) | ast::def_self(_) | ast::def_const(_) | ast::def_arg(_, _) | ast::def_local(_, _) | ast::def_upvar(_, _, _) | ast::def_native_fn(_, _) | ast::def_self(_) { ns_val(ns_any_value) } @@ -1597,15 +1563,6 @@ fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) { ensure_unique(*e, i.span, typaram_names(ty_params), ident_id, "type parameter"); } - ast::item_obj(ob, ty_params, _) { - fn field_name(field: ast::obj_field) -> ident { ret field.ident; } - ensure_unique(*e, i.span, ob.fields, field_name, "object field"); - for m: @ast::method in ob.methods { - check_fn(*e, m.span, m.decl); - } - ensure_unique(*e, i.span, typaram_names(ty_params), ident_id, - "type parameter"); - } ast::item_tag(_, ty_params) { ensure_unique(*e, i.span, typaram_names(ty_params), ident_id, "type parameter"); @@ -1687,7 +1644,7 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) { ast::item_ty(_, _) | ast::item_iface(_, _) { add_name(types, it.span, it.ident); } - ast::item_res(_, _, _, _, _) | ast::item_obj(_, _, _) { + ast::item_res(_, _, _, _, _) { add_name(types, it.span, it.ident); add_name(values, it.span, it.ident); } diff --git a/src/comp/middle/shape.rs b/src/comp/middle/shape.rs index 3f7c6cefca17..b867bd67b8f1 100644 --- a/src/comp/middle/shape.rs +++ b/src/comp/middle/shape.rs @@ -47,7 +47,7 @@ const shape_tag: u8 = 12u8; const shape_box: u8 = 13u8; const shape_struct: u8 = 17u8; const shape_box_fn: u8 = 18u8; -const shape_obj: u8 = 19u8; +const shape_UNUSED: u8 = 19u8; const shape_res: u8 = 20u8; const shape_var: u8 = 21u8; const shape_uniq: u8 = 22u8; @@ -309,8 +309,7 @@ fn add_substr(&dest: [u8], src: [u8]) { dest += src; } -fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint], - is_obj_body: bool) -> [u8] { +fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] { let s = []; alt ty::struct(ccx.tcx, t) { @@ -335,7 +334,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint], s += [shape_vec]; add_bool(s, true); // type is POD let unit_ty = ty::mk_mach_uint(ccx.tcx, ast::ty_u8); - add_substr(s, shape_of(ccx, unit_ty, ty_param_map, is_obj_body)); + add_substr(s, shape_of(ccx, unit_ty, ty_param_map)); } ty::ty_tag(did, tps) { alt tag_kind(ccx, did) { @@ -363,7 +362,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint], add_u16(sub, vec::len(tps) as u16); for tp: ty::t in tps { - let subshape = shape_of(ccx, tp, ty_param_map, is_obj_body); + let subshape = shape_of(ccx, tp, ty_param_map); add_u16(sub, vec::len(subshape) as u16); sub += subshape; } @@ -374,22 +373,22 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint], } ty::ty_box(mt) { s += [shape_box]; - add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body)); + add_substr(s, shape_of(ccx, mt.ty, ty_param_map)); } ty::ty_uniq(mt) { s += [shape_uniq]; - add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body)); + add_substr(s, shape_of(ccx, mt.ty, ty_param_map)); } ty::ty_vec(mt) { s += [shape_vec]; add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty)); - add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body)); + add_substr(s, shape_of(ccx, mt.ty, ty_param_map)); } ty::ty_rec(fields) { s += [shape_struct]; let sub = []; for f: field in fields { - sub += shape_of(ccx, f.mt.ty, ty_param_map, is_obj_body); + sub += shape_of(ccx, f.mt.ty, ty_param_map); } add_substr(s, sub); } @@ -397,12 +396,11 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint], s += [shape_struct]; let sub = []; for elt in elts { - sub += shape_of(ccx, elt, ty_param_map, is_obj_body); + sub += shape_of(ccx, elt, ty_param_map); } add_substr(s, sub); } ty::ty_native_fn(_, _) { s += [shape_u32]; } - ty::ty_obj(_) { s += [shape_obj]; } ty::ty_iface(_, _) { s += [shape_iface]; } ty::ty_res(did, raw_subt, tps) { let subt = ty::substitute_type_params(ccx.tcx, tps, raw_subt); @@ -413,24 +411,19 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint], add_u16(s, id as u16); add_u16(s, vec::len(tps) as u16); for tp: ty::t in tps { - add_substr(s, shape_of(ccx, tp, ty_param_map, is_obj_body)); + add_substr(s, shape_of(ccx, tp, ty_param_map)); } - add_substr(s, shape_of(ccx, subt, ty_param_map, is_obj_body)); + add_substr(s, shape_of(ccx, subt, ty_param_map)); } ty::ty_var(n) { fail "shape_of ty_var"; } ty::ty_param(n, _) { - if is_obj_body { - // Just write in the parameter number. - s += [shape_var, n as u8]; - } else { - // Find the type parameter in the parameter list. - alt vec::position(n, ty_param_map) { - some(i) { s += [shape_var, i as u8]; } - none. { fail "ty param not found in ty_param_map"; } - } + // Find the type parameter in the parameter list. + alt vec::position(n, ty_param_map) { + some(i) { s += [shape_var, i as u8]; } + none. { fail "ty param not found in ty_param_map"; } } } ty::ty_fn({proto: ast::proto_box., _}) { @@ -461,7 +454,7 @@ fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info, while i < ty_param_count { ty_param_map += [i]; i += 1u; } let s = []; - for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map, false); } + for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map); } ret s; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 38f9ec7813af..f5742b5a9842 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2,7 +2,7 @@ // // Some functions here, such as trans_block and trans_expr, return a value -- // the result of the translation to LLVM -- while others, such as trans_fn, -// trans_obj, and trans_item, are called only for the side effect of adding a +// trans_impl, and trans_item, are called only for the side effect of adding a // particular definition to the LLVM IR output we're producing. // // Hopefully useful general knowledge about trans: @@ -42,8 +42,6 @@ import util::ppaux::{ty_to_str, ty_to_short_str}; import trans_common::*; import trans_build::*; - -import trans_objects::{trans_anon_obj, trans_obj}; import tvec = trans_vec; fn type_of_1(bcx: @block_ctxt, t: ty::t) -> TypeRef { @@ -81,7 +79,7 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) -> // - create_llargs_for_fn_args. // - new_fn_ctxt // - trans_args -fn type_of_fn(cx: @crate_ctxt, sp: span, is_method: bool, inputs: [ty::arg], +fn type_of_fn(cx: @crate_ctxt, sp: span, inputs: [ty::arg], output: ty::t, params: [ty::param_bounds]) -> TypeRef { let atys: [TypeRef] = []; @@ -90,22 +88,16 @@ fn type_of_fn(cx: @crate_ctxt, sp: span, is_method: bool, inputs: [ty::arg], let out_ty = T_ptr(type_of_inner(cx, sp, output)); atys += [out_ty]; - // Arg 1: Env (closure-bindings / self-obj) - if is_method { - atys += [T_ptr(cx.rust_object_type)]; - } else { - atys += [T_opaque_cbox_ptr(cx)]; - } + // Arg 1: Environment + atys += [T_opaque_cbox_ptr(cx)]; // Args >2: ty params, if not acquired via capture... - if !is_method { - for bounds in params { - atys += [T_ptr(cx.tydesc_type)]; - for bound in *bounds { - alt bound { - ty::bound_iface(_) { atys += [T_ptr(T_dict())]; } - _ {} - } + for bounds in params { + atys += [T_ptr(cx.tydesc_type)]; + for bound in *bounds { + alt bound { + ty::bound_iface(_) { atys += [T_ptr(T_dict())]; } + _ {} } } } @@ -121,7 +113,7 @@ fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t, // by returns_non_ty_var(t). Make that a postcondition // (see Issue #586) let ret_ty = ty::ty_fn_ret(cx.tcx, fty); - ret type_of_fn(cx, sp, false, ty::ty_fn_args(cx.tcx, fty), + ret type_of_fn(cx, sp, ty::ty_fn_args(cx.tcx, fty), ret_ty, param_bounds); } @@ -179,7 +171,6 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t) let nft = native_fn_wrapper_type(cx, sp, [], t); T_fn_pair(cx, nft) } - ty::ty_obj(_) { cx.rust_object_type } ty::ty_iface(_, _) { T_opaque_iface_ptr(cx) } ty::ty_res(_, sub, tps) { let sub1 = ty::substitute_type_params(cx.tcx, tps, sub); @@ -465,7 +456,7 @@ fn dynastack_alloca(cx: @block_ctxt, t: TypeRef, n: ValueRef, ty: ty::t) -> n); let ti = none; - let lltydesc = get_tydesc(cx, ty, false, tps_normal, ti).result.val; + let lltydesc = get_tydesc(cx, ty, false, ti).result.val; let llresult = Call(dy_cx, dynastack_alloc, [llsz, lltydesc]); ret PointerCast(dy_cx, llresult, T_ptr(t)); @@ -496,11 +487,6 @@ fn simplify_type(ccx: @crate_ctxt, typ: ty::t) -> ty::t { [ty::mk_imm_box(ccx.tcx, ty::mk_nil(ccx.tcx)), ty::mk_imm_box(ccx.tcx, ty::mk_nil(ccx.tcx))]); } - ty::ty_obj(_) { - ret ty::mk_tup(ccx.tcx, - [ty::mk_imm_box(ccx.tcx, ty::mk_nil(ccx.tcx)), - ty::mk_imm_box(ccx.tcx, ty::mk_nil(ccx.tcx))]); - } ty::ty_res(_, sub, tps) { let sub1 = ty::substitute_type_params(ccx.tcx, tps, sub); ret ty::mk_tup(ccx.tcx, @@ -871,7 +857,7 @@ fn trans_malloc_boxed_raw(cx: @block_ctxt, t: ty::t) -> result { let llty = type_of(ccx, sp, box_ptr); let ti = none; - let tydesc_result = get_tydesc(bcx, t, true, tps_normal, ti); + let tydesc_result = get_tydesc(bcx, t, true, ti); let lltydesc = tydesc_result.result.val; bcx = tydesc_result.result.bcx; let rval = Call(cx, ccx.upcalls.malloc, @@ -899,7 +885,7 @@ fn trans_malloc_boxed(cx: @block_ctxt, t: ty::t) -> fn field_of_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool, field: int) -> result { let ti = none::<@tydesc_info>; - let tydesc = get_tydesc(cx, t, escapes, tps_normal, ti).result; + let tydesc = get_tydesc(cx, t, escapes, ti).result; ret rslt(tydesc.bcx, GEPi(tydesc.bcx, tydesc.val, [0, field])); } @@ -936,8 +922,8 @@ fn linearize_ty_params(cx: @block_ctxt, t: ty::t) -> fn trans_stack_local_derived_tydesc(cx: @block_ctxt, llsz: ValueRef, llalign: ValueRef, llroottydesc: ValueRef, - llfirstparam: ValueRef, n_params: uint, - obj_params: uint) -> ValueRef { + llfirstparam: ValueRef, n_params: uint) + -> ValueRef { let llmyroottydesc = alloca(cx, bcx_ccx(cx).tydesc_type); // By convention, desc 0 is the root descriptor. @@ -954,39 +940,29 @@ fn trans_stack_local_derived_tydesc(cx: @block_ctxt, llsz: ValueRef, [0, abi::tydesc_field_size]); store_inbounds(cx, llalign, llmyroottydesc, [0, abi::tydesc_field_align]); - store_inbounds(cx, C_uint(ccx, obj_params), llmyroottydesc, + // FIXME legacy field, can be dropped + store_inbounds(cx, C_uint(ccx, 0u), llmyroottydesc, [0, abi::tydesc_field_obj_params]); ret llmyroottydesc; } -// Objects store their type parameters differently (in the object itself -// rather than in the type descriptor). -tag ty_param_storage { tps_normal; tps_obj(uint); } - fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool, - storage: ty_param_storage, &static_ti: option::t<@tydesc_info>) -> result { alt cx.fcx.derived_tydescs.find(t) { some(info) { // If the tydesc escapes in this context, the cached derived // tydesc also has to be one that was marked as escaping. - if !(escapes && !info.escapes) && storage == tps_normal { + if !(escapes && !info.escapes) { ret rslt(cx, info.lltydesc); } } none. {/* fall through */ } } - let is_obj_body; - alt storage { - tps_normal. { is_obj_body = false; } - tps_obj(_) { is_obj_body = true; } - } - bcx_ccx(cx).stats.n_derived_tydescs += 1u; let bcx = new_raw_block_ctxt(cx.fcx, cx.fcx.llderivedtydescs); let tys = linearize_ty_params(bcx, t); - let root_ti = get_static_tydesc(bcx, t, tys.params, is_obj_body); + let root_ti = get_static_tydesc(bcx, t, tys.params); static_ti = some::<@tydesc_info>(root_ti); lazily_emit_all_tydesc_glue(cx, static_ti); let root = root_ti.tydesc; @@ -1022,14 +998,6 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool, PointerCast(bcx, llparamtydescs, T_ptr(T_ptr(bcx_ccx(bcx).tydesc_type))); - // The top bit indicates whether this type descriptor describes an object - // (0) or a function (1). - let obj_params; - alt storage { - tps_normal. { obj_params = 0u; } - tps_obj(np) { obj_params = np; } - } - let v; if escapes { let ccx = bcx_ccx(bcx); @@ -1037,13 +1005,11 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool, Call(bcx, ccx.upcalls.get_type_desc, [C_null(T_ptr(T_nil())), sz.val, align.val, C_uint(ccx, 1u + n_params), llfirstparam, - C_uint(ccx, obj_params)]); + C_uint(ccx, 0u)]); v = td_val; } else { - v = - trans_stack_local_derived_tydesc(bcx, sz.val, align.val, root, - llfirstparam, n_params, - obj_params); + v = trans_stack_local_derived_tydesc(bcx, sz.val, align.val, root, + llfirstparam, n_params); } bcx.fcx.derived_tydescs.insert(t, {lltydesc: v, escapes: escapes}); ret rslt(cx, v); @@ -1052,7 +1018,7 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool, type get_tydesc_result = {kind: tydesc_kind, result: result}; fn get_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool, - storage: ty_param_storage, &static_ti: option::t<@tydesc_info>) + &static_ti: option::t<@tydesc_info>) -> get_tydesc_result { // Is the supplied type a type param? If so, return the passed-in tydesc. @@ -1076,22 +1042,21 @@ fn get_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool, // Does it contain a type param? If so, generate a derived tydesc. if ty::type_contains_params(bcx_tcx(cx), t) { ret {kind: tk_derived, - result: get_derived_tydesc(cx, t, escapes, storage, static_ti)}; + result: get_derived_tydesc(cx, t, escapes, static_ti)}; } // Otherwise, generate a tydesc if necessary, and return it. - let info = get_static_tydesc(cx, t, [], false); - static_ti = some::<@tydesc_info>(info); + let info = get_static_tydesc(cx, t, []); + static_ti = some(info); ret {kind: tk_static, result: rslt(cx, info.tydesc)}; } -fn get_static_tydesc(cx: @block_ctxt, t: ty::t, ty_params: [uint], - is_obj_body: bool) -> @tydesc_info { +fn get_static_tydesc(cx: @block_ctxt, t: ty::t, ty_params: [uint]) + -> @tydesc_info { alt bcx_ccx(cx).tydescs.find(t) { some(info) { ret info; } none. { bcx_ccx(cx).stats.n_static_tydescs += 1u; - let info = declare_tydesc(cx.fcx.lcx, cx.sp, t, ty_params, - is_obj_body); + let info = declare_tydesc(cx.fcx.lcx, cx.sp, t, ty_params); bcx_ccx(cx).tydescs.insert(t, info); ret info; } @@ -1134,9 +1099,8 @@ fn set_glue_inlining(cx: @local_ctxt, f: ValueRef, t: ty::t) { // Generates the declaration for (but doesn't emit) a type descriptor. -fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint], - is_obj_body: bool) -> - @tydesc_info { +fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint]) + -> @tydesc_info { log(debug, "+++ declare_tydesc " + ty_to_str(cx.ccx.tcx, t)); let ccx = cx.ccx; let llsize; @@ -1171,8 +1135,7 @@ fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint], mutable drop_glue: none::, mutable free_glue: none::, mutable cmp_glue: none::, - ty_params: ty_params, - is_obj_body: is_obj_body}; + ty_params: ty_params}; log(debug, "--- declare_tydesc " + ty_to_str(cx.ccx.tcx, t)); ret info; } @@ -1275,8 +1238,7 @@ fn emit_tydescs(ccx: @crate_ctxt) { some(v) { ccx.stats.n_real_glues += 1u; v } }; - let shape = shape::shape_of(ccx, key, ti.ty_params, - ti.is_obj_body); + let shape = shape::shape_of(ccx, key, ti.ty_params); let shape_tables = llvm::LLVMConstPointerCast(ccx.shape_cx.llshapetables, T_ptr(T_i8())); @@ -1389,16 +1351,14 @@ fn make_free_glue(bcx: @block_ctxt, v: ValueRef, t: ty::t) { ty::ty_vec(_) | ty::ty_str. { tvec::make_free_glue(bcx, PointerCast(bcx, v, type_of_1(bcx, t)), t) } - ty::ty_obj(_) | ty::ty_iface(_, _) { - // Call through the obj's own fields-drop glue first. + ty::ty_iface(_, _) { + // Call through the box's own fields-drop glue first. // Then free the body. - // (Same code of ifaces, whose layout is similar) let ccx = bcx_ccx(bcx); - let llbox_ty = T_opaque_obj_ptr(ccx); + let llbox_ty = T_opaque_iface_ptr(ccx); let b = PointerCast(bcx, v, llbox_ty); let body = GEPi(bcx, b, [0, abi::box_rc_field_body]); - let tydescptr = - GEPi(bcx, body, [0, abi::obj_body_elt_tydesc]); + let tydescptr = GEPi(bcx, body, [0, 0]); let tydesc = Load(bcx, tydescptr); let ti = none; call_tydesc_glue_full(bcx, body, tydesc, @@ -1435,10 +1395,6 @@ fn make_drop_glue(bcx: @block_ctxt, v0: ValueRef, t: ty::t) { ty::ty_uniq(_) | ty::ty_vec(_) | ty::ty_str. | ty::ty_send_type. { free_ty(bcx, Load(bcx, v0), t) } - ty::ty_obj(_) { - let box_cell = GEPi(bcx, v0, [0, abi::obj_field_box]); - decr_refcnt_maybe_free(bcx, Load(bcx, box_cell), t) - } ty::ty_res(did, inner, tps) { trans_res_drop(bcx, v0, did, inner, tps) } @@ -1482,7 +1438,7 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id, let args = [cx.fcx.llretptr, null_env_ptr(cx)]; for tp: ty::t in tps { let ti: option::t<@tydesc_info> = none; - let td = get_tydesc(cx, tp, false, tps_normal, ti).result; + let td = get_tydesc(cx, tp, false, ti).result; args += [td.val]; cx = td.bcx; } @@ -1508,7 +1464,7 @@ fn decr_refcnt_maybe_free(cx: @block_ctxt, box_ptr: ValueRef, t: ty::t) let rc_adj_cx = new_sub_block_ctxt(cx, "rc--"); let free_cx = new_sub_block_ctxt(cx, "free"); let next_cx = new_sub_block_ctxt(cx, "next"); - let llbox_ty = T_opaque_obj_ptr(ccx); + let llbox_ty = T_opaque_iface_ptr(ccx); let box_ptr = PointerCast(cx, box_ptr, llbox_ty); let null_test = IsNull(cx, box_ptr); CondBr(cx, null_test, next_cx.llbb, rc_adj_cx.llbb); @@ -1738,10 +1694,6 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t, } ret next_cx; } - ty::ty_obj(_) { - let box_cell_a = GEPi(cx, av, [0, abi::obj_field_box]); - ret iter_boxpp(cx, box_cell_a, f); - } _ { bcx_ccx(cx).sess.unimpl("type in iter_structural_ty"); } } ret cx; @@ -1876,7 +1828,7 @@ fn call_tydesc_glue_full(cx: @block_ctxt, v: ValueRef, tydesc: ValueRef, fn call_tydesc_glue(cx: @block_ctxt, v: ValueRef, t: ty::t, field: int) -> @block_ctxt { let ti: option::t<@tydesc_info> = none::<@tydesc_info>; - let {bcx: bcx, val: td} = get_tydesc(cx, t, false, tps_normal, ti).result; + let {bcx: bcx, val: td} = get_tydesc(cx, t, false, ti).result; call_tydesc_glue_full(bcx, v, td, field, ti); ret bcx; } @@ -1898,7 +1850,7 @@ fn call_cmp_glue(cx: @block_ctxt, lhs: ValueRef, rhs: ValueRef, t: ty::t, let llrawlhsptr = BitCast(bcx, lllhs, T_ptr(T_i8())); let llrawrhsptr = BitCast(bcx, llrhs, T_ptr(T_i8())); let ti = none::<@tydesc_info>; - r = get_tydesc(bcx, t, false, tps_normal, ti).result; + r = get_tydesc(bcx, t, false, ti).result; let lltydesc = r.val; bcx = r.bcx; lazily_emit_tydesc_glue(bcx, abi::tydesc_field_cmp_glue, ti); @@ -2591,7 +2543,7 @@ type lval_result = {bcx: @block_ctxt, val: ValueRef, kind: lval_kind}; tag callee_env { null_env; is_closure; - obj_env(ValueRef); + self_env(ValueRef); dict_env(ValueRef, ValueRef); } type lval_maybe_callee = {bcx: @block_ctxt, @@ -2647,7 +2599,7 @@ fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id) for t in tys { // TODO: Doesn't always escape. let ti = none; - let td = get_tydesc(bcx, t, true, tps_normal, ti).result; + let td = get_tydesc(bcx, t, true, ti).result; tis += [ti]; bcx = td.bcx; tydescs += [td.val]; @@ -2702,10 +2654,6 @@ fn trans_local_var(cx: @block_ctxt, def: ast::def) -> local_var_result { ast::def_local(did, _) | ast::def_binding(did) { ret take_local(cx.fcx.lllocals, did.node); } - ast::def_obj_field(did, _) { - assert (cx.fcx.llobjfields.contains_key(did.node)); - ret { val: cx.fcx.llobjfields.get(did.node), kind: owned }; - } ast::def_self(did) { let slf = option::get(cx.fcx.llself); let ptr = PointerCast(cx, slf.v, T_ptr(type_of_or_i8(cx, slf.t))); @@ -2766,35 +2714,6 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id) } } -fn trans_object_field(bcx: @block_ctxt, o: @ast::expr, field: ast::ident) - -> {bcx: @block_ctxt, mthptr: ValueRef, objptr: ValueRef} { - let {bcx, val} = trans_temp_expr(bcx, o); - let {bcx, val, ty} = autoderef(bcx, val, ty::expr_ty(bcx_tcx(bcx), o)); - ret trans_object_field_inner(bcx, val, field, ty); -} - -fn trans_object_field_inner(bcx: @block_ctxt, o: ValueRef, - field: ast::ident, o_ty: ty::t) - -> {bcx: @block_ctxt, mthptr: ValueRef, objptr: ValueRef} { - let ccx = bcx_ccx(bcx), tcx = ccx.tcx; - let mths = alt ty::struct(tcx, o_ty) { ty::ty_obj(ms) { ms } }; - - let ix = option::get(ty::method_idx(field, mths)); - let vtbl = Load(bcx, GEPi(bcx, o, [0, abi::obj_field_vtbl])); - let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u)); - vtbl = PointerCast(bcx, vtbl, vtbl_type); - - let v = GEPi(bcx, vtbl, [0, ix as int]); - let fn_ty: ty::t = ty::mk_fn(tcx, mths[ix].fty); - let ret_ty = ty::ty_fn_ret(tcx, fn_ty); - // FIXME: constrain ty_obj? - let ll_fn_ty = type_of_fn(ccx, bcx.sp, true, - ty::ty_fn_args(tcx, fn_ty), ret_ty, []); - v = Load(bcx, PointerCast(bcx, v, T_ptr(T_ptr(ll_fn_ty)))); - ret {bcx: bcx, mthptr: v, objptr: o}; -} - - fn trans_rec_field(bcx: @block_ctxt, base: @ast::expr, field: ast::ident) -> lval_result { let {bcx, val} = trans_temp_expr(bcx, base); @@ -2859,7 +2778,7 @@ fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr, fn expr_is_lval(bcx: @block_ctxt, e: @ast::expr) -> bool { let ccx = bcx_ccx(bcx); - ty::expr_is_lval(ccx.method_map, ccx.tcx, e) + ty::expr_is_lval(ccx.method_map, e) } fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee { @@ -2879,11 +2798,6 @@ fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee { some(typeck::method_iface(off)) { ret trans_impl::trans_iface_callee(bcx, e, base, off); } - none. { // An object method - let of = trans_object_field(bcx, base, ident); - ret {bcx: of.bcx, val: of.mthptr, kind: owned, - env: obj_env(of.objptr), generic: none}; - } } } } @@ -2948,7 +2862,7 @@ fn maybe_add_env(bcx: @block_ctxt, c: lval_maybe_callee) -> (lval_kind, ValueRef) { alt c.env { is_closure. { (c.kind, c.val) } - obj_env(_) | dict_env(_, _) { + self_env(_) | dict_env(_, _) { fail "Taking the value of a method does not work yet (issue #435)"; } null_env. { @@ -3230,7 +3144,7 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, llargs += [PointerCast(cx, llretslot, llretty)]; } else { llargs += [llretslot]; } - // Arg 1: Env (closure-bindings / self-obj) + // Arg 1: Env (closure-bindings / self value) llargs += [llenv]; // Args >2: ty_params ... @@ -3277,7 +3191,7 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr, null_env. { llenv = llvm::LLVMGetUndef(T_opaque_cbox_ptr(bcx_ccx(cx))); } - obj_env(e) { llenv = e; } + self_env(e) { llenv = e; } dict_env(dict, e) { llenv = e; dict_param = some(dict); } is_closure. { // It's a closure. Have to fetch the elements @@ -3639,9 +3553,6 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt { else { ret lval_to_dps(bcx, a, dest); } } ast::expr_cast(val, _) { ret trans_cast(bcx, val, e.id, dest); } - ast::expr_anon_obj(anon_obj) { - ret trans_anon_obj(bcx, e.span, anon_obj, e.id, dest); - } ast::expr_call(f, args, _) { ret trans_call(bcx, f, args, e.id, dest); } @@ -3855,7 +3766,7 @@ fn trans_log(lvl: @ast::expr, cx: @block_ctxt, e: @ast::expr) -> @block_ctxt { let log_bcx = sub.bcx; let ti = none::<@tydesc_info>; - let r = get_tydesc(log_bcx, e_ty, false, tps_normal, ti).result; + let r = get_tydesc(log_bcx, e_ty, false, ti).result; log_bcx = r.bcx; let lltydesc = r.val; @@ -4350,8 +4261,6 @@ fn new_local_ctxt(ccx: @crate_ctxt) -> @local_ctxt { let pth: [str] = []; ret @{path: pth, module_path: [ccx.link_meta.name], - obj_typarams: [], - obj_fields: [], ccx: ccx}; } @@ -4404,7 +4313,6 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, sp: span, llfndecl: ValueRef, mutable llobstacktoken: none::, mutable llself: none::, llargs: new_int_hash::(), - llobjfields: new_int_hash::(), lllocals: new_int_hash::(), llupvars: new_int_hash::(), mutable lltyparams: [], @@ -4440,33 +4348,28 @@ fn create_llargs_for_fn_args(cx: @fn_ctxt, ty_self: self_arg, // way. let arg_n = 2u; alt ty_self { - obj_self(tt) | impl_self(tt) { + impl_self(tt) { cx.llself = some({v: cx.llenv, t: tt}); } no_self. {} } - alt ty_self { - obj_self(_) {} - _ { - for tp in ty_params { - let lltydesc = llvm::LLVMGetParam(cx.llfn, arg_n), dicts = none; - arg_n += 1u; - for bound in *fcx_tcx(cx).ty_param_bounds.get(tp.id) { - alt bound { - ty::bound_iface(_) { - let dict = llvm::LLVMGetParam(cx.llfn, arg_n); - arg_n += 1u; - dicts = some(alt dicts { - none. { [dict] } - some(ds) { ds + [dict] } - }); - } - _ {} - } + for tp in ty_params { + let lltydesc = llvm::LLVMGetParam(cx.llfn, arg_n), dicts = none; + arg_n += 1u; + for bound in *fcx_tcx(cx).ty_param_bounds.get(tp.id) { + alt bound { + ty::bound_iface(_) { + let dict = llvm::LLVMGetParam(cx.llfn, arg_n); + arg_n += 1u; + dicts = some(alt dicts { + none. { [dict] } + some(ds) { ds + [dict] } + }); + } + _ {} } - cx.lltyparams += [{desc: lltydesc, dicts: dicts}]; } - } + cx.lltyparams += [{desc: lltydesc, dicts: dicts}]; } // Populate the llargs field of the function context with the ValueRefs @@ -4517,54 +4420,6 @@ fn arg_tys_of_fn(ccx: @crate_ctxt, id: ast::node_id) -> [ty::arg] { } } -fn populate_fn_ctxt_from_llself(fcx: @fn_ctxt, llself: val_self_pair) { - let ccx = fcx_ccx(fcx); - let bcx = llstaticallocas_block_ctxt(fcx); - let field_tys: [ty::t] = []; - for f: ast::obj_field in bcx.fcx.lcx.obj_fields { - field_tys += [node_id_type(ccx, f.id)]; - } - // Synthesize a tuple type for the fields so that GEP_tup_like() can work - // its magic. - - let fields_tup_ty = ty::mk_tup(fcx.lcx.ccx.tcx, field_tys); - let n_typarams = vec::len::(bcx.fcx.lcx.obj_typarams); - let llobj_box_ty: TypeRef = T_obj_ptr(ccx, n_typarams); - let box_cell = GEPi(bcx, llself.v, [0, abi::obj_field_box]); - let box_ptr = Load(bcx, box_cell); - box_ptr = PointerCast(bcx, box_ptr, llobj_box_ty); - let obj_typarams = - GEPi(bcx, box_ptr, [0, abi::box_rc_field_body, - abi::obj_body_elt_typarams]); - - // The object fields immediately follow the type parameters, so we skip - // over them to get the pointer. - let obj_fields = - PointerCast(bcx, GEPi(bcx, obj_typarams, [1]), - T_ptr(type_of_or_i8(bcx, fields_tup_ty))); - - let i: int = 0; - for p: ast::ty_param in fcx.lcx.obj_typarams { - let lltyparam: ValueRef = - GEPi(bcx, obj_typarams, [0, i]); - lltyparam = Load(bcx, lltyparam); - fcx.lltyparams += [{desc: lltyparam, dicts: none}]; - i += 1; - } - i = 0; - for f: ast::obj_field in fcx.lcx.obj_fields { - // FIXME: silly check - check type_is_tup_like(bcx, fields_tup_ty); - let rslt = GEP_tup_like(bcx, fields_tup_ty, obj_fields, [0, i]); - bcx = llstaticallocas_block_ctxt(fcx); - let llfield = rslt.val; - fcx.llobjfields.insert(f.id, llfield); - i += 1; - } - fcx.llstaticallocas = bcx.llbb; -} - - // Ties up the llstaticallocas -> llloadenv -> llderivedtydescs -> // lldynamicallocas -> lltop edges, and builds the return block. fn finish_fn(fcx: @fn_ctxt, lltop: BasicBlockRef) { @@ -4578,7 +4433,7 @@ fn finish_fn(fcx: @fn_ctxt, lltop: BasicBlockRef) { RetVoid(ret_cx); } -tag self_arg { obj_self(ty::t); impl_self(ty::t); no_self; } +tag self_arg { impl_self(ty::t); no_self; } // trans_closure: Builds an LLVM function out of a source function. // If the function closes over its environment a closure will be @@ -4592,12 +4447,6 @@ fn trans_closure(cx: @local_ctxt, sp: span, decl: ast::fn_decl, // Set up arguments to the function. let fcx = new_fn_ctxt_w_id(cx, sp, llfndecl, id, decl.cf); create_llargs_for_fn_args(fcx, ty_self, decl.inputs, ty_params); - alt ty_self { - obj_self(_) { - populate_fn_ctxt_from_llself(fcx, option::get(fcx.llself)); - } - _ { } - } // Create the first basic block in the function and keep a handle on it to // pass to finish_fn later. @@ -4612,7 +4461,7 @@ fn trans_closure(cx: @local_ctxt, sp: span, decl: ast::fn_decl, // This call to trans_block is the place where we bridge between // translation calls that don't have a return value (trans_crate, - // trans_mod, trans_item, trans_obj, et cetera) and those that do + // trans_mod, trans_item, et cetera) and those that do // (trans_block, trans_expr, et cetera). if ty::type_is_bot(cx.ccx.tcx, block_ty) || ty::type_is_nil(cx.ccx.tcx, block_ty) || @@ -5063,12 +4912,6 @@ fn trans_item(cx: @local_ctxt, item: ast::item) { } } } - ast::item_obj(ob, tps, ctor_id) { - let sub_cx = - @{obj_typarams: tps, obj_fields: ob.fields - with *extend_path(cx, item.ident)}; - trans_obj(sub_cx, item.span, ob, ctor_id, tps); - } ast::item_impl(tps, _, _, ms) { trans_impl::trans_impl(cx, item.ident, ms, item.id, tps); } @@ -5180,7 +5023,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, ty: ty::mk_vec(ccx.tcx, {ty: unit_ty, mut: ast::imm})}; // FIXME: mk_nil should have a postcondition let nt = ty::mk_nil(ccx.tcx); - let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, []); + let llfty = type_of_fn(ccx, sp, [vecarg_ty], nt, []); let llfdecl = decl_fn(ccx.llmod, "_rust_main", lib::llvm::LLVMCCallConv, llfty); @@ -5278,7 +5121,7 @@ fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, x: ty::t) -> TypeRef { alt ty::struct(cx.tcx, x) { ty::ty_native_fn(args, out) { - ret type_of_fn(cx, sp, false, args, out, param_bounds); + ret type_of_fn(cx, sp, args, out, param_bounds); } } } @@ -5378,9 +5221,6 @@ fn collect_item(ccx: @crate_ctxt, abi: @mutable option::t, ast::item_fn(_, tps, _) { register_fn(ccx, i.span, new_pt, "fn", tps, i.id); } - ast::item_obj(ob, tps, ctor_id) { - register_fn(ccx, i.span, new_pt, "obj_ctor", tps, ctor_id); - } ast::item_impl(tps, _, _, methods) { let name = i.ident + int::str(i.id); for m in methods { @@ -5716,7 +5556,6 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, upcalls: upcall::declare_upcalls(targ_cfg, tn, tydesc_type, llmod), - rust_object_type: T_rust_object(), tydesc_type: tydesc_type, int_type: int_type, float_type: float_type, diff --git a/src/comp/middle/trans_closure.rs b/src/comp/middle/trans_closure.rs index d4221ea2d254..a7db4b22eb8c 100644 --- a/src/comp/middle/trans_closure.rs +++ b/src/comp/middle/trans_closure.rs @@ -222,7 +222,7 @@ fn allocate_cbox(bcx: @block_ctxt, let ti = none; let tydesc_ty = if xchgheap { cbox_ty } else { cbox_norc_ty }; let {bcx, val:lltydesc} = - get_tydesc(bcx, tydesc_ty, true, tps_normal, ti).result; + get_tydesc(bcx, tydesc_ty, true, ti).result; let malloc = { if xchgheap { ccx.upcalls.shared_malloc} else { ccx.upcalls.malloc } @@ -315,7 +315,7 @@ fn store_environment( let ti = none; let {result:closure_td, _} = - trans::get_tydesc(bcx, cbox_ty, true, tps_normal, ti); + trans::get_tydesc(bcx, cbox_ty, true, ti); trans::lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, ti); trans::lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti); trans::lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti); diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 1073234923a3..0368a4c7cdf5 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -46,8 +46,7 @@ type tydesc_info = mutable drop_glue: option::t, mutable free_glue: option::t, mutable cmp_glue: option::t, - ty_params: [uint], - is_obj_body: bool}; + ty_params: [uint]}; /* * A note on nomenclature of linking: "upcall", "extern" and "native". @@ -112,7 +111,6 @@ type crate_ctxt = dict_map: typeck::dict_map, stats: stats, upcalls: @upcall::upcalls, - rust_object_type: TypeRef, tydesc_type: TypeRef, int_type: TypeRef, float_type: TypeRef, @@ -127,8 +125,6 @@ type crate_ctxt = type local_ctxt = {path: [str], module_path: [str], - obj_typarams: [ast::ty_param], - obj_fields: [ast::obj_field], ccx: @crate_ctxt}; // Types used for llself. @@ -156,8 +152,7 @@ type fn_ctxt = // Points to the current task. // Points to the current environment (bindings of variables to - // values), if this is a regular function; points to the current - // object, if this is a method. + // values), if this is a regular function // Points to where the return value of this function should end // up. @@ -185,7 +180,7 @@ type fn_ctxt = // The token used to clear the dynamic allocas at the end of this frame. - // The 'self' object currently in use in this function, if there + // The 'self' value currently in use in this function, if there // is one. // If this function is actually a iter, a block containing the @@ -196,9 +191,6 @@ type fn_ctxt = // Maps arguments to allocas created for them in llallocas. - // Maps fields in objects to pointers into the interior of - // llself's body. - // Maps the def_ids for local variables to the allocas created for // them in llallocas. @@ -240,7 +232,6 @@ type fn_ctxt = mutable llobstacktoken: option::t, mutable llself: option::t, llargs: hashmap, - llobjfields: hashmap, lllocals: hashmap, llupvars: hashmap, mutable lltyparams: [fn_ty_param], @@ -331,7 +322,7 @@ fn get_res_dtor(ccx: @crate_ctxt, sp: span, did: ast::def_id, inner_t: ty::t) let nil_res = ty::mk_nil(ccx.tcx); // FIXME: Silly check -- mk_nil should have a postcondition check non_ty_var(ccx, nil_res); - let f_t = type_of_fn(ccx, sp, false, + let f_t = type_of_fn(ccx, sp, [{mode: ast::by_ref, ty: inner_t}], nil_res, *param_bounds); ret trans::get_extern_const(ccx.externs, ccx.llmod, @@ -566,17 +557,6 @@ fn set_struct_body(t: TypeRef, elts: [TypeRef]) unsafe { fn T_empty_struct() -> TypeRef { ret T_struct([]); } -// NB: This will return something different every time it's called. If -// you need a generic object type that matches the type of your -// existing objects, use ccx.rust_object_type. Calling -// T_rust_object() again will return a different one. -fn T_rust_object() -> TypeRef { - let t = T_named_struct("rust_object"); - let e = T_ptr(T_empty_struct()); - set_struct_body(t, [e, e]); - ret t; -} - // A dict is, in reality, a vtable pointer followed by zero or more pointers // to tydescs and other dicts that it closes over. But the types and number of // those are rarely known to the code that needs to manipulate them, so they @@ -745,19 +725,6 @@ fn T_captured_tydescs(cx: @crate_ctxt, n: uint) -> TypeRef { ret T_struct(vec::init_elt::(T_ptr(cx.tydesc_type), n)); } -fn T_obj_ptr(cx: @crate_ctxt, n_captured_tydescs: uint) -> TypeRef { - // This function is not publicly exposed because it returns an incomplete - // type. The dynamically-sized fields follow the captured tydescs. - - fn T_obj(cx: @crate_ctxt, n_captured_tydescs: uint) -> TypeRef { - ret T_struct([T_ptr(cx.tydesc_type), - T_captured_tydescs(cx, n_captured_tydescs)]); - } - ret T_ptr(T_box(cx, T_obj(cx, n_captured_tydescs))); -} - -fn T_opaque_obj_ptr(cx: @crate_ctxt) -> TypeRef { ret T_obj_ptr(cx, 0u); } - fn T_opaque_iface_ptr(cx: @crate_ctxt) -> TypeRef { let tdptr = T_ptr(cx.tydesc_type); T_ptr(T_box(cx, T_struct([tdptr, tdptr, T_i8()]))) diff --git a/src/comp/middle/trans_impl.rs b/src/comp/middle/trans_impl.rs index 55886df07d55..634b5842839d 100644 --- a/src/comp/middle/trans_impl.rs +++ b/src/comp/middle/trans_impl.rs @@ -65,7 +65,7 @@ fn trans_self_arg(bcx: @block_ctxt, base: @ast::expr) -> result { fn trans_static_callee(bcx: @block_ctxt, e: @ast::expr, base: @ast::expr, did: ast::def_id) -> lval_maybe_callee { let {bcx, val} = trans_self_arg(bcx, base); - {env: obj_env(val) with lval_static_fn(bcx, did, e.id)} + {env: self_env(val) with lval_static_fn(bcx, did, e.id)} } fn wrapper_fn_ty(ccx: @crate_ctxt, dict_ty: TypeRef, m: ty::method) @@ -92,7 +92,7 @@ fn trans_vtable_callee(bcx: @block_ctxt, self: ValueRef, dict: ValueRef, let tptys = ty::node_id_to_type_params(tcx, fld_expr.id); for t in vec::tail_n(tptys, vec::len(tptys) - vec::len(*method.tps)) { let ti = none; - let td = get_tydesc(bcx, t, true, tps_normal, ti).result; + let td = get_tydesc(bcx, t, true, ti).result; tis += [ti]; tydescs += [td.val]; bcx = td.bcx; @@ -158,8 +158,7 @@ fn trans_vtable(ccx: @crate_ctxt, id: ast::node_id, name: str, fn trans_wrapper(ccx: @crate_ctxt, pt: [ast::ident], llfty: TypeRef, fill: block(ValueRef, @block_ctxt) -> @block_ctxt) -> ValueRef { - let lcx = @{path: pt, module_path: [], - obj_typarams: [], obj_fields: [], ccx: ccx}; + let lcx = @{path: pt, module_path: [], ccx: ccx}; let name = link::mangle_internal_name_by_path(ccx, pt); let llfn = decl_internal_cdecl_fn(ccx.llmod, name, llfty); let fcx = new_fn_ctxt(lcx, ast_util::dummy_sp(), llfn); @@ -370,7 +369,7 @@ fn get_dict_ptrs(bcx: @block_ctxt, origin: typeck::dict_origin) let ptrs = [get_vtable(ccx, impl_did)]; let origin = 0u, ti = none, bcx = bcx; vec::iter2(*impl_params, tys) {|param, ty| - let rslt = get_tydesc(bcx, ty, true, tps_normal, ti).result; + let rslt = get_tydesc(bcx, ty, true, ti).result; ptrs += [rslt.val]; bcx = rslt.bcx; for bound in *param { @@ -401,8 +400,7 @@ fn trans_cast(bcx: @block_ctxt, val: @ast::expr, id: ast::node_id, dest: dest) let body_ty = ty::mk_tup(tcx, [ty::mk_type(tcx), ty::mk_type(tcx), val_ty]); let ti = none; - let {bcx, val: tydesc} = get_tydesc(bcx, body_ty, true, - tps_normal, ti).result; + let {bcx, val: tydesc} = get_tydesc(bcx, body_ty, true, ti).result; lazily_emit_all_tydesc_glue(bcx, ti); let {bcx, box, body: box_body} = trans_malloc_boxed(bcx, body_ty); Store(bcx, tydesc, GEPi(bcx, box_body, [0, 0])); diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs deleted file mode 100644 index b4edb2b1cf29..000000000000 --- a/src/comp/middle/trans_objects.rs +++ /dev/null @@ -1,951 +0,0 @@ -// Translation of object-related things to LLVM IR. - -import core::{str, option, vec}; -import option::{none, some}; - -import lib::llvm::{llvm, True}; -import lib::llvm::llvm::{TypeRef, ValueRef}; - -import back::abi; -import back::link::{mangle_internal_name_by_path, - mangle_internal_name_by_path_and_seq}; -import syntax::{ast, ast_util}; -import syntax::codemap::span; - -import trans_common::*; -import trans::*; -import trans_build::*; - -import driver::session::session; - -export trans_anon_obj; -export trans_obj; - -// trans_obj: create an LLVM function that is the object constructor for the -// object being translated. -fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id, - ty_params: [ast::ty_param]) { - - // To make a function, we have to create a function context and, inside - // that, a number of block contexts for which code is generated. - let ccx = cx.ccx; - let llctor_decl; - alt ccx.item_ids.find(ctor_id) { - some(x) { llctor_decl = x; } - _ { cx.ccx.sess.span_fatal(sp, "unbound llctor_decl in trans_obj"); } - } - - // Much like trans_fn, we must create an LLVM function, but since we're - // starting with an ast::_obj rather than an ast::_fn, we have some setup - // work to do. - - // The fields of our object will become the arguments to the function - // we're creating. - let fn_args: [ast::arg] = []; - for f: ast::obj_field in ob.fields { - fn_args += [{mode: ast::by_copy, ty: f.ty, ident: f.ident, - id: f.id}]; - } - let fcx = new_fn_ctxt(cx, sp, llctor_decl); - - // Create the first block context in the function and keep a handle on it - // to pass to finish_fn later. - let bcx = new_top_block_ctxt(fcx); - let lltop = bcx.llbb; - - // Both regular arguments and type parameters are handled here. - create_llargs_for_fn_args(fcx, no_self, fn_args, ty_params); - let arg_tys: [ty::arg] = arg_tys_of_fn(ccx, ctor_id); - bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys); - - // Pick up the type of this object by looking at our own output type, that - // is, the output type of the object constructor we're building. - let self_ty = ty::ret_ty_of_fn(ccx.tcx, ctor_id); - - // Set up the two-word pair that we're going to return from the object - // constructor we're building. The two elements of this pair will be a - // vtable pointer and a body pointer. (llretptr already points to the - // place where this two-word pair should go; it was pre-allocated by the - // caller of the function.) - let pair = bcx.fcx.llretptr; - - // Grab onto the first and second elements of the pair. - // abi::obj_field_vtbl and abi::obj_field_box simply specify words 0 and 1 - // of 'pair'. - let pair_vtbl = GEPi(bcx, pair, [0, abi::obj_field_vtbl]); - let pair_box = GEPi(bcx, pair, [0, abi::obj_field_box]); - - // Make a vtable for this object: a static array of pointers to functions. - // It will be located in the read-only memory of the executable we're - // creating and will contain ValueRefs for all of this object's methods. - // create_vtbl returns a pointer to the vtable, which we store. - let vtbl = create_vtbl(cx, sp, self_ty, ob, ty_params, none, []); - vtbl = PointerCast(bcx, vtbl, T_ptr(T_empty_struct())); - - Store(bcx, vtbl, pair_vtbl); - - // Next we have to take care of the other half of the pair we're - // returning: a boxed (reference-counted) tuple containing a tydesc, - // typarams, and fields. - let llbox_ty: TypeRef = T_ptr(T_empty_struct()); - - if vec::len(ty_params) == 0u && - vec::len(arg_tys) == 0u { - // If the object we're translating has no fields or type parameters, - // there's not much to do. - - // Store null into pair, if no args or typarams. - Store(bcx, C_null(llbox_ty), pair_box); - } else { - let obj_fields: [ty::t] = []; - for a: ty::arg in arg_tys { obj_fields += [a.ty]; } - - let tps: [ty::t] = []; - let tydesc_ty = ty::mk_type(ccx.tcx); - for tp: ast::ty_param in ty_params { tps += [tydesc_ty]; } - - // Synthesize an object body type and hand it off to - // trans_malloc_boxed, which allocates a box, including space for a - // refcount. - let body_ty: ty::t = - create_object_body_type(ccx.tcx, obj_fields, tps, none); - - // We have to get this type descriptor now so that - // trans_malloc_boxed() doesn't generate a type descriptor with the - // wrong storage type and override the type descriptor we're about to - // generate. - let ti = none; - let storage = tps_obj(vec::len(ty_params)); - let body_td = get_tydesc(bcx, body_ty, true, storage, ti).result; - bcx = body_td.bcx; - lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti); - lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti); - - let box = trans_malloc_boxed(bcx, body_ty); - bcx = box.bcx; - let body = box.body; - - // Put together a tydesc for the body, so that the object can later be - // freed by calling through its tydesc. - - // Every object (not just those with type parameters) needs to have a - // tydesc to describe its body, since all objects have unknown type to - // the user of the object. So the tydesc is needed to keep track of - // the types of the object's fields, so that the fields can be freed - // later. - - // postcondition on create_object_body_type? - check type_is_tup_like(bcx, body_ty); - let body_tydesc = - GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]); - bcx = body_tydesc.bcx; - - check type_is_tup_like(bcx, body_ty); - let r = - GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_typarams]); - bcx = r.bcx; - let body_typarams = r.val; - - Store(bcx, body_td.val, body_tydesc.val); - - // Copy the object's type parameters and fields into the space we - // allocated for the object body. (This is something like saving the - // lexical environment of a function in its closure: the "captured - // typarams" are any type parameters that are passed to the object - // constructor and are then available to the object's methods. - // Likewise for the object's fields.) - - // Copy typarams into captured typarams. - // TODO: can we just get typarams_ty out of body_ty instead? - let typarams_ty: ty::t = ty::mk_tup(ccx.tcx, tps); - let i: int = 0; - for tp: ast::ty_param in ty_params { - let typaram = bcx.fcx.lltyparams[i].desc; - // Silly check - check type_is_tup_like(bcx, typarams_ty); - let capture = - GEP_tup_like(bcx, typarams_ty, body_typarams, [0, i]); - bcx = capture.bcx; - bcx = copy_val(bcx, INIT, capture.val, typaram, tydesc_ty); - i += 1; - } - - // Copy args into body fields. - // how to get rid of this check? - check type_is_tup_like(bcx, body_ty); - let body_fields = - GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]); - bcx = body_fields.bcx; - // TODO: can we just get fields_ty out of body_ty instead? - let fields_ty = ty::mk_tup(ccx.tcx, obj_fields); - i = 0; - for f: ast::obj_field in ob.fields { - alt bcx.fcx.llargs.find(f.id) { - some(local_mem(arg)) { - // Silly check - check type_is_tup_like(bcx, fields_ty); - let field = - GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]); - bcx = memmove_ty(field.bcx, field.val, arg, arg_tys[i].ty); - i += 1; - } - } - } - - // Store box ptr in outer pair. - let p = PointerCast(bcx, box.box, llbox_ty); - Store(bcx, p, pair_box); - } - build_return(bcx); - - // Insert the mandatory first few basic blocks before lltop. - finish_fn(fcx, lltop); -} - -// trans_anon_obj: create and return a pointer to an object. This code -// differs from trans_obj in that, rather than creating an object constructor -// function and putting it in the generated code as an object item, we are -// instead "inlining" the construction of the object and returning the object -// itself. -fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj, - id: ast::node_id, dest: trans::dest) -> @block_ctxt { - let bcx = bcx; - if dest == trans::ignore { - alt anon_obj.inner_obj { - some(e) { ret trans::trans_expr(bcx, e, trans::ignore); } - none. { ret bcx; } - } - } - - let ccx = bcx_ccx(bcx); - - // Fields. FIXME (part of issue #538): Where do we fill in the field - // *values* from the outer object? - let additional_fields: [ast::anon_obj_field] = []; - let additional_field_vals: [result] = []; - let additional_field_tys: [ty::t] = []; - alt anon_obj.fields { - none. { } - some(fields) { - additional_fields = fields; - for f: ast::anon_obj_field in fields { - additional_field_tys += [node_id_type(ccx, f.id)]; - additional_field_vals += [trans_temp_expr(bcx, f.expr)]; - } - } - } - - // Get the type of the eventual entire anonymous object, possibly with - // extensions. NB: This type includes both inner and outer methods. - let outer_obj_ty = ty::node_id_to_type(ccx.tcx, id); - - // Create a vtable for the anonymous object. - - // create_vtbl() wants an ast::_obj and all we have is an ast::anon_obj, - // so we need to roll our own. NB: wrapper_obj includes only outer - // methods, not inner ones. - let wrapper_obj: ast::_obj = - {fields: - vec::map(additional_fields, - ast_util::obj_field_from_anon_obj_field), - methods: anon_obj.methods}; - - let inner_obj_ty: ty::t; - let vtbl; - alt anon_obj.inner_obj { - none. { - // We need a dummy inner_obj_ty for setting up the object body later. - inner_obj_ty = ty::mk_type(ccx.tcx); - - // If there's no inner_obj -- that is, if we're creating a new object - // from nothing rather than extending an existing object -- then we - // just pass the outer object to create_vtbl(). Our vtable won't need - // to have any forwarding slots. - vtbl = - create_vtbl(bcx.fcx.lcx, sp, outer_obj_ty, wrapper_obj, [], none, - additional_field_tys); - } - some(e) { - // TODO: What makes more sense to get the type of an expr -- calling - // ty::expr_ty(ccx.tcx, e) on it or calling - // ty::node_id_to_type(ccx.tcx, id) on its id? - inner_obj_ty = ty::expr_ty(ccx.tcx, e); - //inner_obj_ty = ty::node_id_to_type(ccx.tcx, e.id); - - // If there's a inner_obj, we pass its type along to create_vtbl(). - // Part of what create_vtbl() will do is take the set difference of - // methods defined on the original and methods being added. For every - // method defined on the original that does *not* have one with a - // matching name and type being added, we'll need to create a - // forwarding slot. And, of course, we need to create a normal vtable - // entry for every method being added. - vtbl = - create_vtbl(bcx.fcx.lcx, sp, outer_obj_ty, wrapper_obj, [], - some(inner_obj_ty), additional_field_tys); - } - } - - vtbl = PointerCast(bcx, vtbl, T_ptr(T_empty_struct())); - - // Next we have to take care of the other half of the pair we're - // returning: a boxed (reference-counted) tuple containing a tydesc, - // typarams, fields, and a pointer to our inner_obj. - let llbox_ty: TypeRef = T_ptr(T_empty_struct()); - - let box = C_null(llbox_ty); - if vec::len(additional_fields) > 0u || anon_obj.inner_obj != none { - // Synthesize a type for the object body and hand it off to - // trans_malloc_boxed, which allocates a box, including space for a - // refcount. - let body_ty: ty::t = - create_object_body_type(ccx.tcx, additional_field_tys, [], - some(inner_obj_ty)); - let box_r = trans_malloc_boxed(bcx, body_ty); - box = box_r.box; - bcx = box_r.bcx; - add_clean_free(bcx, box, false); - let body = box_r.body; - - // Put together a tydesc for the body, so that the object can later be - // freed by calling through its tydesc. - - // Every object (not just those with type parameters) needs to have a - // tydesc to describe its body, since all objects have unknown type to - // the user of the object. So the tydesc is needed to keep track of - // the types of the object's fields, so that the fields can be freed - // later. - // postcondition on create_object_body_type? - check type_is_tup_like(bcx, body_ty); - let body_tydesc = - GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]); - bcx = body_tydesc.bcx; - let ti = none; - let body_td = get_tydesc(bcx, body_ty, true, tps_normal, ti).result; - lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti); - lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti); - bcx = body_td.bcx; - Store(bcx, body_td.val, body_tydesc.val); - - // Copy the object's fields into the space we allocated for the object - // body. (This is something like saving the lexical environment of a - // function in its closure: the fields were passed to the object - // constructor and are now available to the object's methods. - check type_is_tup_like(bcx, body_ty); - let body_fields = - GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]); - bcx = body_fields.bcx; - let i: int = 0; - for f: ast::anon_obj_field in additional_fields { - // FIXME (part of issue #538): make this work eventually, when we - // have additional field exprs in the AST. - load_if_immediate(bcx, additional_field_vals[i].val, - additional_field_tys[i]); - let fields_ty: ty::t = ty::mk_tup(ccx.tcx, additional_field_tys); - // Silly check - check type_is_tup_like(bcx, fields_ty); - let field = GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]); - bcx = field.bcx; - bcx = - copy_val(bcx, INIT, field.val, additional_field_vals[i].val, - additional_field_tys[i]); - i += 1; - } - - // If there's a inner_obj, copy a pointer to it into the object's - // body. - alt anon_obj.inner_obj { - none. { } - some(e) { - // If inner_obj (the object being extended) exists, translate it. - // Translating inner_obj returns a ValueRef (pointer to a 2-word - // value) wrapped in a result. - check type_is_tup_like(bcx, body_ty); - let {bcx: cx, val: body_inner_obj} = GEP_tup_like - (bcx, body_ty, body, [0, abi::obj_body_elt_inner_obj]); - bcx = trans_expr_save_in(cx, e, body_inner_obj); - } - } - revoke_clean(bcx, box); - box = PointerCast(bcx, box, llbox_ty); - } - let pair = trans::get_dest_addr(dest); - let pair_vtbl = GEPi(bcx, pair, [0, abi::obj_field_vtbl]); - Store(bcx, vtbl, pair_vtbl); - let pair_box = GEPi(bcx, pair, [0, abi::obj_field_box]); - Store(bcx, box, pair_box); - ret bcx; -} - -// Used only inside create_vtbl and create_backwarding_vtbl to distinguish -// different kinds of slots we'll have to create. -tag vtbl_mthd { - - // Normal methods are complete AST nodes, but for forwarding methods, the - // only information we'll have about them is their type. - normal_mthd(@ast::method); - fwding_mthd(@ty::method); -} - -// Alphabetize ast::methods by ident. A helper for create_vtbl. -fn ast_mthd_lteq(&&a: @ast::method, &&b: @ast::method) -> bool { - ret str::lteq(a.ident, b.ident); -} - -// Alphabetize vtbl_mthds by ident. A helper for create_vtbl. -fn vtbl_mthd_lteq(a: vtbl_mthd, b: vtbl_mthd) -> bool { - alt a { - normal_mthd(ma) { - alt b { - normal_mthd(mb) { ret str::lteq(ma.ident, mb.ident); } - fwding_mthd(mb) { ret str::lteq(ma.ident, mb.ident); } - } - } - fwding_mthd(ma) { - alt b { - normal_mthd(mb) { ret str::lteq(ma.ident, mb.ident); } - fwding_mthd(mb) { ret str::lteq(ma.ident, mb.ident); } - } - } - } -} - -// filtering_fn: Used by create_vtbl to filter a list of methods to remove the -// ones that we don't need forwarding slots for. -fn filtering_fn(cx: @local_ctxt, m: vtbl_mthd, addtl_meths: [@ast::method]) -> - option::t { - - // Since m is a fwding_mthd, and we're checking to see if it's in - // addtl_meths (which only contains normal_mthds), we can't just check if - // it's a member of addtl_meths. Instead, we have to go through - // addtl_meths and see if there's some method in it that has the same name - // as m. - alt m { - fwding_mthd(fm) { - for am: @ast::method in addtl_meths { - if str::eq(am.ident, fm.ident) { ret none; } - } - ret some(fwding_mthd(fm)); - } - normal_mthd(_) { - cx.ccx.sess.bug("create_vtbl(): shouldn't be any \ - normal_mthds in meths here"); - } - } -} - -// create_vtbl: Create a vtable for a regular object or for an outer anonymous -// object, and return a pointer to it. -fn create_vtbl(cx: @local_ctxt, sp: span, outer_obj_ty: ty::t, ob: ast::_obj, - ty_params: [ast::ty_param], inner_obj_ty: option::t, - additional_field_tys: [ty::t]) -> ValueRef { - - let llmethods: [ValueRef] = []; - - alt inner_obj_ty { - none. { - // We're creating a vtable for a regular object, or for an anonymous - // object that doesn't extend an existing one. - - // Sort and process all the methods. - let meths = - std::sort::merge_sort(bind ast_mthd_lteq(_, _), ob.methods); - - for m: @ast::method in meths { - llmethods += - [process_normal_mthd(cx, m, outer_obj_ty, ty_params)]; - } - } - some(inner_obj_ty) { - // We're creating a vtable for an anonymous object that extends an - // existing one. - - // The vtable needs to contain 'forwarding slots' for any methods that - // were on the inner object and are not being overridden by the outer - // one. To find the set of methods that we need forwarding slots for, - // we take the set difference of { methods on the original object } - // and { methods being added, whether entirely new or overriding }. - - let meths: [vtbl_mthd] = []; - - // Gather up methods on the inner object. - alt ty::struct(cx.ccx.tcx, inner_obj_ty) { - ty::ty_obj(inner_obj_methods) { - for m: ty::method in inner_obj_methods { - meths += [fwding_mthd(@m)]; - } - } - _ { - cx.ccx.sess.bug("create_vtbl(): trying to extend a \ - non-object"); - } - } - - // Filter out any methods that we don't need forwarding slots for - // because they're being overridden. - let f = bind filtering_fn(cx, _, ob.methods); - meths = vec::filter_map(meths, f); - - // And now add the additional ones, both overriding ones and entirely - // new ones. These will just be normal methods. - for m: @ast::method in ob.methods { meths += [normal_mthd(m)]; } - - // Sort all the methods and process them. - meths = - std::sort::merge_sort(bind vtbl_mthd_lteq(_, _), meths); - - // To create forwarding methods, we'll need a "backwarding" vtbl. See - // create_backwarding_vtbl and process_bkwding_method for details. - let backwarding_vtbl: ValueRef = - create_backwarding_vtbl(cx, sp, inner_obj_ty, outer_obj_ty); - - for m: vtbl_mthd in meths { - alt m { - normal_mthd(nm) { - llmethods += - [process_normal_mthd(cx, nm, outer_obj_ty, ty_params)]; - } - fwding_mthd(fm) { - llmethods += - [process_fwding_mthd(cx, sp, fm, ty_params, inner_obj_ty, - backwarding_vtbl, - additional_field_tys)]; - } - } - } - } - } - - ret finish_vtbl(cx, llmethods, "vtbl"); -} - -// create_backwarding_vtbl: Create a vtable for the inner object of an -// anonymous object, so that any self-calls made from the inner object's -// methods get redirected appropriately. -fn create_backwarding_vtbl(cx: @local_ctxt, sp: span, inner_obj_ty: ty::t, - outer_obj_ty: ty::t) -> ValueRef { - - // This vtbl needs to have slots for all of the methods on an inner - // object, and it needs to forward them to the corresponding slots on the - // outer object. All we know about either one are their types. - - let llmethods: [ValueRef] = []; - let meths: [ty::method] = []; - - // Gather up methods on the inner object. - alt ty::struct(cx.ccx.tcx, inner_obj_ty) { - ty::ty_obj(inner_obj_methods) { - for m: ty::method in inner_obj_methods { meths += [m]; } - } - _ { - // Shouldn't happen. - cx.ccx.sess.bug("create_backwarding_vtbl(): trying to extend a \ - non-object"); - } - } - - // Methods should have already been sorted, so no need to do so again. - for m: ty::method in meths { - // We pass outer_obj_ty to process_fwding_mthd() because it's the one - // being forwarded to. - llmethods += [process_bkwding_mthd(cx, sp, @m, [], outer_obj_ty, [])]; - } - ret finish_vtbl(cx, llmethods, "backwarding_vtbl"); -} - -// finish_vtbl: Given a vector of vtable entries, create the table in -// read-only memory and return a pointer to it. -fn finish_vtbl(cx: @local_ctxt, llmethods: [ValueRef], name: str) -> - ValueRef { - let vtbl = C_struct(llmethods); - let vtbl_name = mangle_internal_name_by_path(cx.ccx, cx.path + [name]); - let gvar = - str::as_buf(vtbl_name, - {|buf| - llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl), buf) - }); - llvm::LLVMSetInitializer(gvar, vtbl); - llvm::LLVMSetGlobalConstant(gvar, True); - llvm::LLVMSetLinkage(gvar, - lib::llvm::LLVMInternalLinkage as llvm::Linkage); - ret gvar; -} - -// begin_fn: Set up an LLVM function for backwarding and forwarding functions. -fn begin_fn(cx: @local_ctxt, sp: span, m: @ty::method, - ty_params: [ast::ty_param], fn_name: str) -> ValueRef { - - // Create a local context that's aware of the name of the method we're - // creating. - let mcx: @local_ctxt = @{path: cx.path + ["method", m.ident] with *cx}; - - // Make up a name for the function. - let s: str = - mangle_internal_name_by_path_and_seq(mcx.ccx, mcx.path, fn_name); - - // Get the function's type and declare it. - let llfn_ty: TypeRef = type_of_meth(cx.ccx, sp, m, ty_params); - let llfn: ValueRef = decl_internal_cdecl_fn(cx.ccx.llmod, s, llfn_ty); - - ret llfn; -} - -// process_bkwding_mthd: Create the backwarding function that appears in a -// backwarding vtable slot. -// -// Backwarding functions are used in situations where method calls dispatch -// back through an outer object. For example, suppose an inner object has -// methods foo and bar, and bar contains the call self.foo(). We extend that -// object with a foo method that overrides the inner foo. Now, a call to -// outer.bar() should send us to to inner.bar() via a normal forwarding -// function, and then to self.foo(). But inner.bar() was already compiled -// under the assumption that self.foo() is inner.foo(), when we really want to -// reach outer.foo(). So, we give 'self' a vtable of backwarding functions, -// one for each method on inner, each of which takes all the same arguments as -// the corresponding method on inner does, calls that method on outer, and -// returns the value returned from that call. -fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method, - ty_params: [ast::ty_param], outer_obj_ty: ty::t, - _additional_field_tys: [ty::t]) -> ValueRef { - - let llbackwarding_fn = begin_fn(cx, sp, m, ty_params, "backwarding_fn"); - let fcx = new_fn_ctxt(cx, sp, llbackwarding_fn); - let bcx = new_top_block_ctxt(fcx); - let lltop = bcx.llbb; - - // The self-object will arrive in the backwarding function via the - // llenv argument, but we need to jump past the first item in the - // self-stack to get to the one we really want. - - // Cast to self-stack's type. - let llenv = - PointerCast(bcx, fcx.llenv, - T_ptr(T_struct([cx.ccx.rust_object_type, - T_ptr(cx.ccx.rust_object_type)]))); - let llself_obj_ptr = GEPi(bcx, llenv, [0, 1]); - llself_obj_ptr = Load(bcx, llself_obj_ptr); - - // Cast it back to pointer-to-object-type, so LLVM won't complain. - llself_obj_ptr = - PointerCast(bcx, llself_obj_ptr, T_ptr(cx.ccx.rust_object_type)); - - // The 'llretptr' that will arrive in the backwarding function we're - // creating also needs to be the correct type. Cast it to the method's - // return type, if necessary. - let llretptr = fcx.llretptr; - let ccx = cx.ccx; - if ty::type_contains_params(ccx.tcx, m.fty.output) { - let m_output = m.fty.output; - check non_ty_var(ccx, m_output); - let llretty = type_of_inner(ccx, sp, m_output); - llretptr = PointerCast(bcx, llretptr, T_ptr(llretty)); - } - - // Get the index of the method we want. - let ix: uint = 0u; - alt ty::struct(bcx_tcx(bcx), outer_obj_ty) { - ty::ty_obj(methods) { - ix = option::get(ty::method_idx(m.ident, methods)); - } - _ { - // Shouldn't happen. - cx.ccx.sess.bug("process_bkwding_mthd(): non-object type passed \ - as outer_obj_ty"); - } - } - - // Pick out the method being backwarded to from the outer object's vtable. - let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u)); - - let llouter_obj_vtbl = - GEPi(bcx, llself_obj_ptr, [0, abi::obj_field_vtbl]); - llouter_obj_vtbl = Load(bcx, llouter_obj_vtbl); - llouter_obj_vtbl = PointerCast(bcx, llouter_obj_vtbl, vtbl_type); - - let llouter_mthd = - GEPi(bcx, llouter_obj_vtbl, [0, ix as int]); - - // Set up the outer method to be called. - let llouter_mthd_ty = type_of_meth(bcx_ccx(bcx), sp, m, ty_params); - llouter_mthd = - PointerCast(bcx, llouter_mthd, T_ptr(T_ptr(llouter_mthd_ty))); - llouter_mthd = Load(bcx, llouter_mthd); - - // Set up the three implicit arguments to the outer method we'll need to - // call. - let llouter_mthd_args: [ValueRef] = [llretptr, llself_obj_ptr]; - - // Copy the explicit arguments that are being passed into the forwarding - // function (they're in fcx.llargs) to llouter_mthd_args. - - let a: uint = 2u; // retptr, env come first - for arg: ty::arg in m.fty.inputs { - llouter_mthd_args += [llvm::LLVMGetParam(llbackwarding_fn, a)]; - a += 1u; - } - - // And, finally, call the outer method. - Call(bcx, llouter_mthd, llouter_mthd_args); - - build_return(bcx); - finish_fn(fcx, lltop); - - ret llbackwarding_fn; - -} - -// process_fwding_mthd: Create the forwarding function that appears in a -// vtable slot for method calls that need to forward to another object. A -// helper function for create_vtbl. -// -// Forwarding functions are used for method calls that fall through to an -// inner object. For example, suppose an inner object has method foo and we -// extend it with a method bar. The only version of 'foo' we have is on the -// inner object, but we would like to be able to call outer.foo(). So we use -// a forwarding function to make the foo method available on the outer object. -// It takes all the same arguments as the foo method on the inner object does, -// calls inner.foo() with those arguments, and then returns the value returned -// from that call. (The inner object won't exist until run-time, but we know -// its type statically.) -fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method, - ty_params: [ast::ty_param], inner_obj_ty: ty::t, - backwarding_vtbl: ValueRef, - additional_field_tys: [ty::t]) -> ValueRef unsafe { - - // Create a new function context and block context for the function, - // holding onto a pointer to the first block. - let llforwarding_fn = begin_fn(cx, sp, m, ty_params, "forwarding_fn"); - let fcx = new_fn_ctxt(cx, sp, llforwarding_fn); - let bcx = new_top_block_ctxt(fcx); - let lltop = bcx.llbb; - - // The outer object will arrive in the forwarding function via the llenv - // argument. - let llself_obj_ptr = fcx.llenv; - - // The 'llretptr' that will arrive in the forwarding function we're - // creating also needs to be the correct type. Cast it to the method's - // return type, if necessary. - let llretptr = fcx.llretptr; - let ccx = cx.ccx; - if ty::type_contains_params(ccx.tcx, m.fty.output) { - let m_output = m.fty.output; - check non_ty_var(ccx, m_output); - let llretty = type_of_inner(ccx, sp, m_output); - llretptr = PointerCast(bcx, llretptr, T_ptr(llretty)); - } - - // Now, we have to get the the inner_obj's vtbl out of the self_obj. This - // is a multi-step process: - - // First, grab the box out of the self_obj. It contains a refcount and a - // body. - let llself_obj_box = - GEPi(bcx, llself_obj_ptr, [0, abi::obj_field_box]); - llself_obj_box = Load(bcx, llself_obj_box); - - let ccx = bcx_ccx(bcx); - let llbox_ty = T_opaque_obj_ptr(ccx); - llself_obj_box = PointerCast(bcx, llself_obj_box, llbox_ty); - - // Now, reach into the box and grab the body. - let llself_obj_body = - GEPi(bcx, llself_obj_box, [0, abi::box_rc_field_body]); - - // Now, we need to figure out exactly what type the body is supposed to be - // cast to. - let body_ty: ty::t = - create_object_body_type(cx.ccx.tcx, additional_field_tys, [], - some(inner_obj_ty)); - // And cast to that type. - // create_object_body_type maybe should have a postcondition... - - let cx_ccx = cx.ccx; - check (type_has_static_size(cx_ccx, body_ty)); - - llself_obj_body = - PointerCast(bcx, llself_obj_body, - T_ptr(type_of(cx_ccx, sp, body_ty))); - - // Now, reach into the body and grab the inner_obj. - check type_is_tup_like(bcx, body_ty); - let llinner_obj = - GEP_tup_like(bcx, body_ty, llself_obj_body, - [0, abi::obj_body_elt_inner_obj]); - bcx = llinner_obj.bcx; - - // And, now, somewhere in inner_obj is a vtable with an entry for the - // method we want. First, pick out the vtable, and then pluck that - // method's entry out of the vtable so that the forwarding function can - // call it. - let llinner_obj_vtbl = - GEPi(bcx, llinner_obj.val, [0, abi::obj_field_vtbl]); - llinner_obj_vtbl = Load(bcx, llinner_obj_vtbl); - - let llinner_obj_body = - GEPi(bcx, llinner_obj.val, [0, abi::obj_field_box]); - llinner_obj_body = Load(bcx, llinner_obj_body); - - // Get the index of the method we want. - let ix: uint = 0u; - alt ty::struct(bcx_tcx(bcx), inner_obj_ty) { - ty::ty_obj(methods) { - ix = option::get(ty::method_idx(m.ident, methods)); - } - _ { - // Shouldn't happen. - cx.ccx.sess.bug("process_fwding_mthd(): non-object type passed \ - as target_obj_ty"); - } - } - - // Pick out the original method from the vtable. - let vtbl_type = T_ptr(T_array(T_ptr(T_nil()), ix + 1u)); - llinner_obj_vtbl = PointerCast(bcx, llinner_obj_vtbl, vtbl_type); - - let llorig_mthd = - GEPi(bcx, llinner_obj_vtbl, [0, ix as int]); - - // Set up the original method to be called. - let llorig_mthd_ty = type_of_meth(bcx_ccx(bcx), sp, m, ty_params); - llorig_mthd = PointerCast(bcx, llorig_mthd, T_ptr(T_ptr(llorig_mthd_ty))); - llorig_mthd = Load(bcx, llorig_mthd); - - // Set up the self-stack. - let self_stack = - alloca(bcx, - T_struct([cx.ccx.rust_object_type, - T_ptr(cx.ccx.rust_object_type)])); - self_stack = - populate_self_stack(bcx, self_stack, llself_obj_ptr, backwarding_vtbl, - llinner_obj_body); - - // Cast self_stack back to pointer-to-object-type to make LLVM happy. - self_stack = PointerCast(bcx, self_stack, T_ptr(cx.ccx.rust_object_type)); - - // Set up the three implicit arguments to the original method we'll need - // to call. - let llorig_mthd_args: [ValueRef] = [llretptr, self_stack]; - - // Copy the explicit arguments that are being passed into the forwarding - // function (they're in fcx.llargs) to llorig_mthd_args. - - let a: uint = 2u; // retptr, env come first - for arg: ty::arg in m.fty.inputs { - llorig_mthd_args += [llvm::LLVMGetParam(llforwarding_fn, a)]; - a += 1u; - } - - // And, finally, call the original (inner) method. - Call(bcx, llorig_mthd, llorig_mthd_args); - - build_return(bcx); - finish_fn(fcx, lltop); - - ret llforwarding_fn; -} - -// create_object_body_type: Synthesize a big structural tuple type for an -// object body: [tydesc, [typaram, ...], [field, ...], inner_obj]. -fn create_object_body_type(tcx: ty::ctxt, fields_ty: [ty::t], - typarams_ty: [ty::t], - maybe_inner_obj_ty: option::t) -> ty::t { - - let tydesc_ty: ty::t = ty::mk_type(tcx); - let typarams_ty_tup: ty::t = ty::mk_tup(tcx, typarams_ty); - let fields_ty_tup: ty::t = ty::mk_tup(tcx, fields_ty); - - let body_ty: ty::t; - alt maybe_inner_obj_ty { - some(inner_obj_ty) { - body_ty = - ty::mk_tup(tcx, - [tydesc_ty, typarams_ty_tup, fields_ty_tup, - inner_obj_ty]); - } - none { - body_ty = - ty::mk_tup(tcx, [tydesc_ty, typarams_ty_tup, fields_ty_tup]); - } - } - - ret body_ty; -} - -// process_normal_mthd: Create the contents of a normal vtable slot. A helper -// function for create_vtbl. -fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t, - ty_params: [ast::ty_param]) -> ValueRef { - - let llfnty = T_nil(); - let ccx = cx.ccx; - alt ty::struct(cx.ccx.tcx, node_id_type(cx.ccx, m.id)) { - ty::ty_fn(f) { - let out = f.output; - check non_ty_var(ccx, out); - llfnty = type_of_fn( - ccx, m.span, true, f.inputs, out, - vec::map(ty_params, {|p| param_bounds(ccx, p)})); - } - } - let mcx: @local_ctxt = - @{path: cx.path + ["method", m.ident] with *cx}; - let s: str = mangle_internal_name_by_path(mcx.ccx, mcx.path); - let llfn: ValueRef = decl_internal_cdecl_fn(ccx.llmod, s, llfnty); - - // Every method on an object gets its node_id inserted into the crate-wide - // item_ids map, together with the ValueRef that points to where that - // method's definition will be in the executable. - ccx.item_ids.insert(m.id, llfn); - ccx.item_symbols.insert(m.id, s); - trans_fn(mcx, m.span, m.decl, m.body, llfn, obj_self(self_ty), ty_params, - m.id); - - ret llfn; -} - -// Update a self-stack structure ([[wrapper_self_pair], self_pair*]) to -// [[backwarding_vtbl*, inner_obj_body*], outer_obj*]. -// -// We do this when we're receiving the outer object in a forwarding function -// via the llenv argument, and we want the forwarding function to call a -// method on a "self" that's inner-obj-shaped, but we also want to hold onto -// the outer obj for potential use later by backwarding functions. -fn populate_self_stack(bcx: @block_ctxt, self_stack: ValueRef, - outer_obj: ValueRef, backwarding_vtbl: ValueRef, - inner_obj_body: ValueRef) -> ValueRef { - - // Drop the outer obj into the second slot. - let self_pair_ptr = GEPi(bcx, self_stack, [0, 1]); - Store(bcx, outer_obj, self_pair_ptr); - - // Drop in the backwarding vtbl. - let wrapper_pair = GEPi(bcx, self_stack, [0, 0]); - let wrapper_vtbl_ptr = GEPi(bcx, wrapper_pair, [0, 0]); - let backwarding_vtbl_cast = - PointerCast(bcx, backwarding_vtbl, T_ptr(T_empty_struct())); - Store(bcx, backwarding_vtbl_cast, wrapper_vtbl_ptr); - - // Drop in the inner obj body. - let wrapper_body_ptr = GEPi(bcx, wrapper_pair, [0, 1]); - Store(bcx, inner_obj_body, wrapper_body_ptr); - - ret self_stack; -} - -fn type_of_meth(ccx: @crate_ctxt, sp: span, m: @ty::method, - tps: [ast::ty_param]) -> TypeRef { - let out_ty = m.fty.output; - check non_ty_var(ccx, out_ty); - type_of_fn(ccx, sp, true, m.fty.inputs, out_ty, - vec::map(tps, {|p| param_bounds(ccx, p)})) -} - -// -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: -// diff --git a/src/comp/middle/trans_vec.rs b/src/comp/middle/trans_vec.rs index 4c8e82c066d9..1704069a8c6b 100644 --- a/src/comp/middle/trans_vec.rs +++ b/src/comp/middle/trans_vec.rs @@ -6,7 +6,7 @@ import back::abi; import trans::{call_memmove, trans_shared_malloc, llsize_of, type_of_or_i8, INIT, copy_val, load_if_immediate, size_of, get_tydesc, - node_id_type, new_sub_block_ctxt, tps_normal, do_spill_noroot, + node_id_type, new_sub_block_ctxt, do_spill_noroot, dest}; import trans_build::*; import trans_common::*; @@ -201,7 +201,7 @@ fn trans_append_literal(bcx: @block_ctxt, vptrptr: ValueRef, vec_ty: ty::t, let elt_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty); let ti = none; let {bcx: bcx, val: td} = - get_tydesc(bcx, elt_ty, false, tps_normal, ti).result; + get_tydesc(bcx, elt_ty, false, ti).result; trans::lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, ti); let opaque_v = PointerCast(bcx, vptrptr, T_ptr(T_ptr(ccx.opaque_vec_type))); diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs index 98860463d196..7d52c5882a3f 100644 --- a/src/comp/middle/tstate/pre_post_conditions.rs +++ b/src/comp/middle/tstate/pre_post_conditions.rs @@ -73,7 +73,6 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) { ccx: ccx}; find_pre_post_fn(fcx, body); } - item_obj(o, _, _) {for m in o.methods { find_pre_post_method(ccx, m); }} item_impl(_, _, _, ms) { for m in ms { find_pre_post_method(ccx, m); } } } } @@ -551,15 +550,6 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) { expr_break. { clear_pp(expr_pp(fcx.ccx, e)); } expr_cont. { clear_pp(expr_pp(fcx.ccx, e)); } expr_mac(_) { fcx.ccx.tcx.sess.bug("unexpanded macro"); } - expr_anon_obj(anon_obj) { - alt anon_obj.inner_obj { - some(ex) { - find_pre_post_expr(fcx, ex); - copy_pre_post(fcx.ccx, e.id, ex); - } - none. { clear_pp(expr_pp(fcx.ccx, e)); } - } - } } } diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs index 40f717038437..adfc4411adb0 100644 --- a/src/comp/middle/tstate/states.rs +++ b/src/comp/middle/tstate/states.rs @@ -609,12 +609,6 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool { } expr_break. { ret pure_exp(fcx.ccx, e.id, pres); } expr_cont. { ret pure_exp(fcx.ccx, e.id, pres); } - expr_anon_obj(anon_obj) { - alt anon_obj.inner_obj { - some(wt) { ret find_pre_post_state_sub(fcx, pres, wt, e.id, none); } - none. { ret pure_exp(fcx.ccx, e.id, pres); } - } - } } } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 3607edb43c3b..fe6e99dbd8a0 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -72,7 +72,6 @@ export mk_mach_float; export mk_native; export mk_native_fn; export mk_nil; -export mk_obj; export mk_iface; export mk_res; export mk_param; @@ -124,7 +123,6 @@ export ty_str; export ty_vec; export ty_native; export ty_nil; -export ty_obj; export ty_iface; export ty_res; export ty_param; @@ -138,7 +136,7 @@ export ty_uint; export ty_uniq; export ty_var; export ty_named; -export same_type, same_method; +export same_type; export ty_var_id; export ty_param_substs_opt_and_ty_to_monotype; export ty_fn_args; @@ -266,7 +264,6 @@ tag sty { ty_rec([field]); ty_fn(fn_ty); ty_native_fn([arg], t); - ty_obj([method]); ty_iface(def_id, [t]); ty_res(def_id, t, [t]); ty_tup([t]); @@ -298,8 +295,6 @@ tag type_err { terr_record_size(uint, uint); terr_record_mutability; terr_record_fields(ast::ident, ast::ident); - terr_meth_count; - terr_obj_meths(ast::ident, ast::ident); terr_arg_count; terr_mode_mismatch(mode, mode); terr_constr_len(uint, uint); @@ -497,12 +492,6 @@ fn mk_raw_ty(cx: ctxt, st: sty) -> @raw_t { ty_native_fn(args, tt) { derive_flags_sig(cx, has_params, has_vars, args, tt); } - ty_obj(meths) { - for m: method in meths { - derive_flags_sig(cx, has_params, has_vars, m.fty.inputs, - m.fty.output); - } - } ty_res(_, tt, tps) { derive_flags_t(cx, has_params, has_vars, tt); for tt: t in tps { derive_flags_t(cx, has_params, has_vars, tt); } @@ -614,8 +603,6 @@ fn mk_native_fn(cx: ctxt, args: [arg], ty: t) -> t { ret gen_ty(cx, ty_native_fn(args, ty)); } -fn mk_obj(cx: ctxt, meths: [method]) -> t { ret gen_ty(cx, ty_obj(meths)); } - fn mk_iface(cx: ctxt, did: ast::def_id, tys: [t]) -> t { ret gen_ty(cx, ty_iface(did, tys)); } @@ -705,12 +692,6 @@ fn walk_ty(cx: ctxt, walker: ty_walk, ty: t) { for a: arg in args { walk_ty(cx, walker, a.ty); } walk_ty(cx, walker, ret_ty); } - ty_obj(methods) { - for m: method in methods { - for a: arg in m.fty.inputs { walk_ty(cx, walker, a.ty); } - walk_ty(cx, walker, m.fty.output); - } - } ty_res(_, sub, tps) { walk_ty(cx, walker, sub); for tp: t in tps { walk_ty(cx, walker, tp); } @@ -797,18 +778,6 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t { } ty = mk_native_fn(cx, new_args, fold_ty(cx, fld, ret_ty)); } - ty_obj(methods) { - let new_methods = vec::map(methods, {|m| - let new_args = vec::map(m.fty.inputs, {|a| - {mode: a.mode, ty: fold_ty(cx, fld, a.ty)} - }); - {ident: m.ident, tps: m.tps, - fty: {inputs: new_args, - output: fold_ty(cx, fld, m.fty.output) - with m.fty}} - }); - ty = mk_obj(cx, new_methods); - } ty_res(did, subty, tps) { let new_tps = []; for tp: t in tps { new_tps += [fold_ty(cx, fld, tp)]; } @@ -850,7 +819,7 @@ fn type_is_bool(cx: ctxt, ty: t) -> bool { fn type_is_structural(cx: ctxt, ty: t) -> bool { alt struct(cx, ty) { ty_rec(_) | ty_tup(_) | ty_tag(_, _) | ty_fn(_) | - ty_native_fn(_, _) | ty_obj(_) | ty_res(_, _, _) { true } + ty_native_fn(_, _) | ty_res(_, _, _) { true } _ { false } } } @@ -1056,9 +1025,6 @@ fn type_kind(cx: ctxt, ty: t) -> kind { ty_native(_) | ty_ptr(_) | ty_send_type. | ty_str. | ty_native_fn(_, _) { kind_sendable } ty_type. { kind_copyable } - // FIXME: obj is broken for now, since we aren't asserting - // anything about its fields. - ty_obj(_) { kind_copyable } ty_fn(f) { proto_kind(f.proto) } ty_opaque_closure_ptr(ck_block.) { kind_noncopyable } ty_opaque_closure_ptr(ck_box.) { kind_copyable } @@ -1233,7 +1199,7 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool { ty_send_type. | ty_type. | ty_native(_) | ty_ptr(_) { result = true; } // Boxed types ty_str. | ty_box(_) | ty_uniq(_) | ty_vec(_) | ty_fn(_) | - ty_native_fn(_, _) | ty_obj(_) | ty_iface(_, _) { result = false; } + ty_native_fn(_, _) | ty_iface(_, _) { result = false; } // Structural types ty_tag(did, tps) { let variants = tag_variants(cx, did); @@ -1417,11 +1383,6 @@ fn hash_type_structure(st: sty) -> uint { // ??? ty_fn(f) { ret hash_fn(27u, f.inputs, f.output); } ty_native_fn(args, rty) { ret hash_fn(28u, args, rty); } - ty_obj(methods) { - let h = 29u; - for m: method in methods { h += (h << 5u) + str::hash(m.ident); } - ret h; - } ty_var(v) { ret hash_uint(30u, v as uint); } ty_param(pid, _) { ret hash_uint(31u, pid); } ty_type. { ret 32u; } @@ -1670,20 +1631,11 @@ fn expr_has_ty_params(cx: ctxt, expr: @ast::expr) -> bool { ret node_id_has_type_params(cx, expr.id); } -fn expr_is_lval(method_map: typeck::method_map, tcx: ty::ctxt, - e: @ast::expr) -> bool { +fn expr_is_lval(method_map: typeck::method_map, e: @ast::expr) -> bool { alt e.node { ast::expr_path(_) | ast::expr_index(_, _) | ast::expr_unary(ast::deref., _) { true } - ast::expr_field(base, ident, _) { - method_map.contains_key(e.id) ? false : { - let basety = type_autoderef(tcx, expr_ty(tcx, base)); - alt struct(tcx, basety) { - ty_obj(_) { false } - ty_rec(_) { true } - } - } - } + ast::expr_field(base, ident, _) { !method_map.contains_key(e.id) } _ { false } } } @@ -2060,35 +2012,6 @@ mod unify { err { err } } } - fn unify_obj(cx: @ctxt, expected_meths: [method], - actual_meths: [method], variance: variance) -> result { - let result_meths: [method] = []; - let i: uint = 0u; - let expected_len: uint = vec::len(expected_meths); - let actual_len: uint = vec::len(actual_meths); - if expected_len != actual_len { ret ures_err(terr_meth_count); } - while i < expected_len { - let e_meth = expected_meths[i]; - let a_meth = actual_meths[i]; - if !str::eq(e_meth.ident, a_meth.ident) { - ret ures_err(terr_obj_meths(e_meth.ident, a_meth.ident)); - } - alt unify_fn(cx, e_meth.fty, a_meth.fty, variance) { - ures_ok(tfn) { - alt struct(cx.tcx, tfn) { - ty_fn(f) { - result_meths += [{ident: e_meth.ident, - tps: a_meth.tps, fty: f}]; - } - } - } - err { ret err; } - } - i += 1u; - } - let t = mk_obj(cx.tcx, result_meths); - ret ures_ok(t); - } // If the given type is a variable, returns the structure of that type. fn resolve_type_structure(tcx: ty_ctxt, vb: @var_bindings, typ: t) -> @@ -2483,14 +2406,6 @@ mod unify { _ { ret ures_err(terr_mismatch); } } } - ty::ty_obj(expected_meths) { - alt struct(cx.tcx, actual) { - ty::ty_obj(actual_meths) { - ret unify_obj(cx, expected_meths, actual_meths, variance); - } - _ { ret ures_err(terr_mismatch); } - } - } ty::ty_constr(expected_t, expected_constrs) { // unify the base types... @@ -2600,13 +2515,6 @@ fn same_type(cx: ctxt, a: t, b: t) -> bool { _ { false } } } -fn same_method(cx: ctxt, a: method, b: method) -> bool { - a.tps == b.tps && a.fty.proto == b.fty.proto && a.ident == b.ident && - vec::all2(a.fty.inputs, b.fty.inputs, - {|a, b| a.mode == b.mode && same_type(cx, a.ty, b.ty) }) && - same_type(cx, a.fty.output, b.fty.output) && - a.fty.ret_style == b.fty.ret_style -} fn type_err_to_str(err: ty::type_err) -> str { alt err { @@ -2639,11 +2547,6 @@ fn type_err_to_str(err: ty::type_err) -> str { "' but found one with field '" + a_fld + "'"; } terr_arg_count. { ret "incorrect number of function parameters"; } - terr_meth_count. { ret "incorrect number of object methods"; } - terr_obj_meths(e_meth, a_meth) { - ret "expected an obj with method '" + e_meth + - "' but found one with method '" + a_meth + "'"; - } terr_mode_mismatch(e_mode, a_mode) { ret "expected argument mode " + mode_str(e_mode) + " but found " + mode_str(a_mode); @@ -2675,7 +2578,7 @@ fn substitute_type_params(cx: ctxt, substs: [ty::t], typ: t) -> t { fn def_has_ty_params(def: ast::def) -> bool { alt def { - ast::def_obj_field(_, _) | ast::def_mod(_) | ast::def_const(_) | + ast::def_mod(_) | ast::def_const(_) | ast::def_arg(_, _) | ast::def_local(_, _) | ast::def_upvar(_, _, _) | ast::def_ty_param(_, _) | ast::def_binding(_) | ast::def_use(_) | ast::def_native_ty(_) | ast::def_self(_) | ast::def_ty(_) { false } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index e3718933caad..c2ac1cea6ed8 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -42,9 +42,8 @@ type dict_map = hashmap; type ty_table = hashmap; -// Used for typechecking the methods of an object. +// Used for typechecking the methods of an impl tag self_info { - self_obj([ast::obj_field], ty::t); self_impl(ty::t); } @@ -102,15 +101,10 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) -> let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node)); ret {bounds: @[], ty: typ}; } - ast::def_obj_field(id, _) { - assert (fcx.locals.contains_key(id.node)); - let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node)); - ret {bounds: @[], ty: typ}; - } ast::def_self(id) { alt get_self_info(fcx.ccx) { - some(self_obj(_, obj_t)) | some(self_impl(obj_t)) { - ret {bounds: @[], ty: obj_t}; + some(self_impl(impl_t)) { + ret {bounds: @[], ty: impl_t}; } } } @@ -356,10 +350,6 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t { } } } - ast::ty_obj(meths) { - let ms = vec::map(meths, {|m| ty_of_ty_method(tcx, mode, m) }); - typ = ty::mk_obj(tcx, ty::sort_methods(ms)); - } ast::ty_constr(t, cs) { let out_cs = []; for constr: @ast::ty_constr in cs { @@ -391,11 +381,6 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item) ast::item_fn(decl, tps, _) { ret ty_of_fn(tcx, mode, decl, tps, local_def(it.id)); } - ast::item_obj(ob, tps, _) { - let t_obj = ty_of_obj(tcx, mode, it.ident, ob, tps); - tcx.tcache.insert(local_def(it.id), t_obj); - ret t_obj; - } ast::item_ty(t, tps) { alt tcx.tcache.find(local_def(it.id)) { some(tpt) { ret tpt; } @@ -541,30 +526,6 @@ fn ty_of_ty_method(tcx: ty::ctxt, mode: mode, m: ast::ty_method) {ident: m.ident, tps: ty_param_bounds(tcx, mode, m.tps), fty: ty_of_fn_decl(tcx, mode, ast::proto_bare, m.decl)} } -fn ty_of_obj(tcx: ty::ctxt, mode: mode, id: ast::ident, ob: ast::_obj, - ty_params: [ast::ty_param]) -> ty::ty_param_bounds_and_ty { - let bounds = ty_param_bounds(tcx, mode, ty_params); - let methods = vec::map(ob.methods, {|m| ty_of_method(tcx, mode, m)}); - let t_obj = ty::mk_named(tcx, ty::mk_obj(tcx, ty::sort_methods(methods)), - @id); - ret {bounds: bounds, ty: t_obj}; -} -fn ty_of_obj_ctor(tcx: ty::ctxt, mode: mode, id: ast::ident, ob: ast::_obj, - ctor_id: ast::node_id, ty_params: [ast::ty_param]) - -> ty::ty_param_bounds_and_ty { - let t_obj = ty_of_obj(tcx, mode, id, ob, ty_params); - let t_inputs: [arg] = []; - for f: ast::obj_field in ob.fields { - let t_field = ast_ty_to_ty(tcx, mode, f.ty); - t_inputs += [{mode: ast::by_copy, ty: t_field}]; - } - let t_fn = ty::mk_fn(tcx, {proto: ast::proto_box, - inputs: t_inputs, output: t_obj.ty, - ret_style: ast::return_val, constraints: []}); - let tpt = {bounds: ty_param_bounds(tcx, mode, ty_params), ty: t_fn}; - tcx.tcache.insert(local_def(ctor_id), tpt); - ret tpt; -} // A convenience function to use a crate_ctxt to resolve names for // ast_ty_to_ty. @@ -766,38 +727,6 @@ mod collect { _ {} } } - ast::item_obj(object, ty_params, ctor_id) { - // Now we need to call ty_of_obj_ctor(); this is the type that - // we write into the table for this item. - ty_of_item(cx.tcx, m_collect, it); - let tpt = ty_of_obj_ctor(cx.tcx, m_collect, it.ident, object, - ctor_id, ty_params); - write::ty_only(cx.tcx, ctor_id, tpt.ty); - // Write the methods into the type table. - // - // FIXME: Inefficient; this ends up calling - // get_obj_method_types() twice. (The first time was above in - // ty_of_obj().) - let m_types = vec::map(object.methods, - {|m| ty_of_method(cx.tcx, m_collect, m)}); - let i = 0u; - for m in object.methods { - write::ty_only(cx.tcx, m.id, - ty::mk_fn(cx.tcx, m_types[i].fty)); - i += 1u; - } - // Write in the types of the object fields. - // - // FIXME: We want to use uint::range() here, but that causes - // an assertion in trans. - let args = ty::ty_fn_args(cx.tcx, tpt.ty); - i = 0u; - while i < vec::len::(args) { - let fld = object.fields[i]; - write::ty_only(cx.tcx, fld.id, args[i].ty); - i += 1u; - } - } ast::item_res(decl, tps, _, dtor_id, ctor_id) { let {bounds, params} = mk_ty_params(cx.tcx, tps); let t_arg = ty_of_arg(cx.tcx, m_collect, decl.inputs[0]); @@ -1190,16 +1119,6 @@ fn gather_locals(ccx: @crate_ctxt, } }; - // Add object fields, if any. - alt get_self_info(ccx) { - some(self_obj(ofs, _)) { - for f in ofs { - assign(f.id, some(ty::node_id_to_type(ccx.tcx, f.id))); - } - } - _ {} - } - // Add formal parameters. let args = ty::ty_fn_args(ccx.tcx, ty::node_id_to_type(ccx.tcx, id)); let i = 0u; @@ -2323,21 +2242,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, _ {} } } - ty::ty_obj(methods) { - alt ty::method_idx(field, methods) { - some(ix) { - if n_tys > 0u { - tcx.sess.span_err(expr.span, - "can't provide type parameters \ - to an obj method"); - } - write::ty_only_fixup(fcx, id, - ty::mk_fn(tcx, methods[ix].fty)); - handled = true; - } - _ {} - } - } _ {} } if !handled { @@ -2408,104 +2312,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, } } } - ast::expr_anon_obj(ao) { - let fields: [ast::anon_obj_field] = []; - alt ao.fields { none. { } some(v) { fields = v; } } - - let method_types: [ty::method] = []; - { - // Outer methods. - for m: @ast::method in ao.methods { - method_types += [ty_of_method(fcx.ccx.tcx, m_check, m)]; - } - - // Inner methods. - - // Typecheck 'inner_obj'. If it exists, it had better have object - // type. - let inner_obj_methods: [ty::method] = []; - let inner_obj_sty: option::t = none; - alt ao.inner_obj { - none. { } - some(e) { - // If there's a inner_obj, we push it onto the self_infos - // stack so that self-calls can be checked within its context - // later. - bot |= check_expr(fcx, e); - let inner_obj_ty = expr_ty(tcx, e); - inner_obj_sty = some(structure_of(fcx, e.span, inner_obj_ty)); - - alt inner_obj_sty { - none. { } - some(sty) { - alt sty { - ty::ty_obj(ms) { inner_obj_methods = ms; } - _ { - // The user is trying to extend a non-object. - tcx.sess.span_fatal - (e.span, syntax::print::pprust::expr_to_str(e) - + " does not have object type"); - } - } - } - } - } - } - - // Whenever an outer method overrides an inner, we need to remove - // that inner from the type. Filter inner_obj_methods to remove - // any methods that share a name with an outer method. - fn filtering_fn(ccx: @crate_ctxt, m: ty::method, - outer_obj_methods: [@ast::method]) -> - option::t { - - for om: @ast::method in outer_obj_methods { - if str::eq(om.ident, m.ident) { - // We'd better be overriding with one of the same - // type. Check to make sure. - let new_type = ty_of_method(ccx.tcx, m_check, om); - if !ty::same_method(ccx.tcx, new_type, m) { - ccx.tcx.sess.span_fatal - (om.span, "attempted to override method " - + m.ident + " with one of a different type"); - } - ret none; - } - } - ret some(m); - } - - let f = bind filtering_fn(fcx.ccx, _, ao.methods); - inner_obj_methods = vec::filter_map(inner_obj_methods, f); - - method_types += inner_obj_methods; - } - - let ot = ty::mk_obj(tcx, ty::sort_methods(method_types)); - - write::ty_only_fixup(fcx, id, ot); - - // Write the methods into the node type table. (This happens in - // collect::convert for regular objects.) - let i = 0u; - while i < vec::len(ao.methods) { - write::ty_only(tcx, ao.methods[i].id, - ty::mk_fn(tcx, method_types[i].fty)); - i += 1u; - } - - fcx.ccx.self_infos += - [self_obj( - vec::map(fields, ast_util::obj_field_from_anon_obj_field), - ot)]; - // Typecheck the methods. - for method: @ast::method in ao.methods { - check_method(fcx.ccx, method); - } - - // Now remove the info from the stack. - vec::pop(fcx.ccx.self_infos); - } _ { tcx.sess.unimpl("expr type in typeck::check_expr"); } } if bot { write::ty_only_fixup(fcx, expr.id, ty::mk_bot(tcx)); } @@ -2832,15 +2638,6 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) { ast::item_res(decl, tps, body, dtor_id, _) { check_fn(ccx, ast::proto_bare, decl, body, dtor_id, none); } - ast::item_obj(ob, tps, _) { - // We're entering an object, so gather up the info we need. - ccx.self_infos += [self_obj(ob.fields, - ccx.tcx.tcache.get(local_def(it.id)).ty)]; - // Typecheck the methods. - for method: @ast::method in ob.methods { check_method(ccx, method); } - // Now remove the info from the stack. - vec::pop(ccx.self_infos); - } ast::item_impl(tps, _, ty, ms) { ccx.self_infos += [self_impl(ast_ty_to_ty(ccx.tcx, m_check, ty))]; for m in ms { check_method(ccx, m); } diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index d770243f3528..bc28ea0480a1 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -18,7 +18,6 @@ mod middle { mod trans_build; mod trans; mod trans_alt; - mod trans_objects; mod trans_uniq; mod trans_closure; mod trans_vec; diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index d519ff0577f1..25d6cda1b715 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -34,7 +34,6 @@ type ty_param = {ident: ident, id: node_id, bounds: @[ty_param_bound]}; tag def { def_fn(def_id, purity); - def_obj_field(def_id, mutability); def_self(def_id); def_mod(def_id); def_native_mod(def_id); @@ -234,7 +233,6 @@ tag expr_ { /* FIXME Would be nice if expr_check desugared to expr_if_check. */ expr_if_check(@expr, blk, option::t<@expr>); - expr_anon_obj(anon_obj); expr_mac(mac); } @@ -318,7 +316,6 @@ tag ty_ { ty_chan(@ty); ty_rec([ty_field]); ty_fn(proto, fn_decl); - ty_obj([ty_method]); ty_tup([@ty]); ty_path(@path, node_id); ty_type; @@ -389,19 +386,6 @@ tag ret_style { type method = {ident: ident, tps: [ty_param], decl: fn_decl, body: blk, id: node_id, span: span}; -type obj_field = {mut: mutability, ty: @ty, ident: ident, id: node_id}; -type anon_obj_field = - {mut: mutability, ty: @ty, expr: @expr, ident: ident, id: node_id}; - -type _obj = {fields: [obj_field], methods: [@method]}; - -type anon_obj = - // New fields and methods, if they exist. - // inner_obj: the original object being extended, if it exists. - {fields: option::t<[anon_obj_field]>, - methods: [@method], - inner_obj: option::t<@expr>}; - type _mod = {view_items: [@view_item], items: [@item]}; tag native_abi { @@ -439,9 +423,6 @@ tag view_item_ { view_item_export([ident], node_id); } -type obj_def_ids = {ty: node_id, ctor: node_id}; - - // Meta-data associated with an item type attribute = spanned; @@ -453,8 +434,8 @@ tag attr_style { attr_outer; attr_inner; } type attribute_ = {style: attr_style, value: meta_item}; -type item = // For objs and resources, this is the type def_id - {ident: ident, attrs: [attribute], id: node_id, node: item_, span: span}; +type item = {ident: ident, attrs: [attribute], + id: node_id, node: item_, span: span}; tag item_ { item_const(@ty, @expr); @@ -463,7 +444,6 @@ tag item_ { item_native_mod(native_mod); item_ty(@ty, [ty_param]); item_tag([variant], [ty_param]); - item_obj(_obj, [ty_param], /* constructor id */node_id); item_res(fn_decl /* dtor */, [ty_param], blk, node_id /* dtor id */, node_id /* ctor id */); item_iface([ty_param], [ty_method]); diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index 4a9c51286c79..d8070aa098d6 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -25,7 +25,7 @@ fn variant_def_ids(d: def) -> {tg: def_id, var: def_id} { fn def_id_of_def(d: def) -> def_id { alt d { - def_fn(id, _) | def_obj_field(id, _) | def_self(id) | def_mod(id) | + def_fn(id, _) | def_self(id) | def_mod(id) | def_native_mod(id) | def_const(id) | def_arg(id, _) | def_local(id, _) | def_variant(_, id) | def_ty(id) | def_ty_param(id, _) | def_binding(id) | def_use(id) | def_native_ty(id) | @@ -215,10 +215,6 @@ fn default_block(stmts1: [@stmt], expr1: option::t<@expr>, id1: node_id) -> {view_items: [], stmts: stmts1, expr: expr1, id: id1, rules: default_blk} } -fn obj_field_from_anon_obj_field(f: anon_obj_field) -> obj_field { - ret {mut: f.mut, ty: f.ty, ident: f.ident, id: f.id}; -} - // This is a convenience function to transfor ternary expressions to if // expressions so that they can be treated the same fn ternary_to_if(e: @expr) -> @expr { diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index a2cb8066a678..54684bca83b6 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -95,7 +95,6 @@ fn nf_native_mod_dummy(_n: native_mod) -> native_mod { fail; } fn nf_variant_dummy(_v: variant) -> variant { fail; } fn nf_ident_dummy(&&_i: ident) -> ident { fail; } fn nf_path_dummy(&&_p: @path) -> @path { fail; } -fn nf_obj_field_dummy(_o: obj_field) -> obj_field { fail; } fn nf_local_dummy(&&_o: @local) -> @local { fail; } /* some little folds that probably aren't useful to have in ast_fold itself*/ @@ -216,14 +215,6 @@ fn noop_fold_item(&&i: @item, fld: ast_fold) -> @item { } fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { - fn fold_obj_field_(of: obj_field, fld: ast_fold) -> obj_field { - ret {mut: of.mut, - ty: fld.fold_ty(of.ty), - ident: fld.fold_ident(of.ident), - id: of.id}; - } - let fold_obj_field = bind fold_obj_field_(_, fld); - ret alt i { item_const(t, e) { item_const(fld.fold_ty(t), fld.fold_expr(e)) } item_fn(decl, typms, body) { @@ -236,11 +227,6 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { item_tag(variants, typms) { item_tag(vec::map(variants, fld.fold_variant), typms) } - item_obj(o, typms, d) { - item_obj({fields: vec::map(o.fields, fold_obj_field), - methods: vec::map(o.methods, fld.fold_method)}, - typms, d) - } item_impl(tps, ifce, ty, methods) { item_impl(tps, option::map(ifce, fld.fold_ty), fld.fold_ty(ty), vec::map(methods, fld.fold_method)) @@ -327,29 +313,6 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { span: field.span}; } let fold_field = bind fold_field_(_, fld); - fn fold_anon_obj_(ao: anon_obj, fld: ast_fold) -> anon_obj { - fn fold_anon_obj_field_(aof: anon_obj_field, fld: ast_fold) -> - anon_obj_field { - ret {mut: aof.mut, - ty: fld.fold_ty(aof.ty), - expr: fld.fold_expr(aof.expr), - ident: fld.fold_ident(aof.ident), - id: aof.id}; - } - let fold_anon_obj_field = bind fold_anon_obj_field_(_, fld); - - - ret {fields: - alt ao.fields { - option::none. { ao.fields } - option::some(v) { - option::some(vec::map(v, fold_anon_obj_field)) - } - }, - methods: vec::map(ao.methods, fld.fold_method), - inner_obj: option::map(ao.inner_obj, fld.fold_expr)} - } - let fold_anon_obj = bind fold_anon_obj_(_, fld); let fold_mac = bind fold_mac_(_, fld); @@ -439,7 +402,6 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_if_check(fld.fold_expr(cond), fld.fold_block(tr), option::map(fl, fld.fold_expr)) } - expr_anon_obj(ao) { expr_anon_obj(fold_anon_obj(ao)) } expr_mac(mac) { expr_mac(fold_mac(mac)) } } } diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 314add8289ce..57f21e6113b8 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -139,8 +139,7 @@ fn bad_expr_word_table() -> hashmap { "cont", "ret", "be", "fail", "type", "resource", "check", "assert", "claim", "native", "fn", "pure", "unsafe", "block", "import", "export", "let", "const", - "log", "tag", "obj", "copy", "sendfn", "impl", "iface", - "enum"] { + "log", "copy", "sendfn", "impl", "iface", "enum"] { words.insert(word, ()); } words @@ -260,12 +259,12 @@ fn parse_ty_fn(proto: ast::proto, p: parser) -> ast::ty_ { constraints: constrs}); } -fn parse_ty_methods(p: parser, allow_tps: bool) -> [ast::ty_method] { +fn parse_ty_methods(p: parser) -> [ast::ty_method] { parse_seq(token::LBRACE, token::RBRACE, seq_sep_none(), {|p| let flo = p.span.lo; expect_word(p, "fn"); let ident = parse_value_ident(p); - let tps = allow_tps ? parse_ty_params(p) : []; + let tps = parse_ty_params(p); let f = parse_ty_fn(ast::proto_bare, p), fhi = p.last_span.hi; expect(p, token::SEMI); alt f { @@ -490,8 +489,6 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty { } else if eat_word(p, "sendfn") { //(breaks prettyprinting!) p.warn("sendfn is deprecated, use fn~"); t = parse_ty_fn(ast::proto_uniq, p); - } else if eat_word(p, "obj") { - t = ast::ty_obj(parse_ty_methods(p, false)); } else if p.token == token::MOD_SEP || is_ident(p.token) { let path = parse_path(p); t = ast::ty_path(path, p.get_id()); @@ -825,35 +822,6 @@ fn parse_bottom_expr(p: parser) -> pexpr { } else if p.token == token::ELLIPSIS { p.bump(); ret pexpr(mk_mac_expr(p, lo, p.span.hi, ast::mac_ellipsis)); - } else if eat_word(p, "obj") { - // Anonymous object - - // Only make people type () if they're actually adding new fields - let fields: option::t<[ast::anon_obj_field]> = none; - if p.token == token::LPAREN { - p.bump(); - fields = - some(parse_seq_to_end(token::RPAREN, seq_sep(token::COMMA), - parse_anon_obj_field, p)); - } - let meths: [@ast::method] = []; - let inner_obj: option::t<@ast::expr> = none; - expect(p, token::LBRACE); - while p.token != token::RBRACE { - if eat_word(p, "with") { - inner_obj = some(parse_expr(p)); - } else { meths += [parse_method(p, false)]; } - } - hi = p.span.hi; - expect(p, token::RBRACE); - // fields and methods may be *additional* or *overriding* fields - // and methods if there's a inner_obj, or they may be the *only* - // fields and methods if there's no inner_obj. - - // We don't need to pull ".node" out of fields because it's not a - // "spanned". - let ob = {fields: fields, methods: meths, inner_obj: inner_obj}; - ex = ast::expr_anon_obj(ob); } else if eat_word(p, "bind") { let e = parse_expr_res(p, RESTRICT_NO_CALL_EXPRS); fn parse_expr_opt(p: parser) -> option::t<@ast::expr> { @@ -1781,55 +1749,20 @@ fn parse_item_fn(p: parser, purity: ast::purity, ast::item_fn(decl, t.tps, body), attrs); } -fn parse_obj_field(p: parser) -> ast::obj_field { - let mut = parse_mutability(p); - let ident = parse_value_ident(p); - expect(p, token::COLON); - let ty = parse_ty(p, false); - ret {mut: mut, ty: ty, ident: ident, id: p.get_id()}; -} - -fn parse_anon_obj_field(p: parser) -> ast::anon_obj_field { - let mut = parse_mutability(p); - let ident = parse_value_ident(p); - expect(p, token::COLON); - let ty = parse_ty(p, false); - expect(p, token::EQ); - let expr = parse_expr(p); - ret {mut: mut, ty: ty, expr: expr, ident: ident, id: p.get_id()}; -} - -fn parse_method(p: parser, allow_tps: bool) -> @ast::method { +fn parse_method(p: parser) -> @ast::method { let lo = p.span.lo; expect_word(p, "fn"); let ident = parse_value_ident(p); - let tps = allow_tps ? parse_ty_params(p) : []; + let tps = parse_ty_params(p); let decl = parse_fn_decl(p, ast::impure_fn); let body = parse_block(p); @{ident: ident, tps: tps, decl: decl, body: body, id: p.get_id(), span: ast_util::mk_sp(lo, body.span.hi)} } -fn parse_item_obj(p: parser, attrs: [ast::attribute]) -> @ast::item { - let lo = p.last_span.lo; - let ident = parse_value_ident(p); - let ty_params = parse_ty_params(p); - let fields: ast::spanned<[ast::obj_field]> = - parse_seq(token::LPAREN, token::RPAREN, seq_sep(token::COMMA), - parse_obj_field, p); - let meths: [@ast::method] = []; - expect(p, token::LBRACE); - while p.token != token::RBRACE { meths += [parse_method(p, false)]; } - let hi = p.span.hi; - expect(p, token::RBRACE); - let ob: ast::_obj = {fields: fields.node, methods: meths}; - ret mk_item(p, lo, hi, ident, ast::item_obj(ob, ty_params, p.get_id()), - attrs); -} - fn parse_item_iface(p: parser, attrs: [ast::attribute]) -> @ast::item { let lo = p.last_span.lo, ident = parse_ident(p), - tps = parse_ty_params(p), meths = parse_ty_methods(p, true); + tps = parse_ty_params(p), meths = parse_ty_methods(p); ret mk_item(p, lo, p.last_span.hi, ident, ast::item_iface(tps, meths), attrs); } @@ -1861,7 +1794,7 @@ fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item { expect_word(p, "for"); let ty = parse_ty(p, false), meths = []; expect(p, token::LBRACE); - while !eat(p, token::RBRACE) { meths += [parse_method(p, true)]; } + while !eat(p, token::RBRACE) { meths += [parse_method(p)]; } ret mk_item(p, lo, p.last_span.hi, ident, ast::item_impl(tps, ifce, ty, meths), attrs); } @@ -2169,9 +2102,6 @@ fn parse_item(p: parser, attrs: [ast::attribute]) -> option::t<@ast::item> { ret some(parse_item_type(p, attrs)); } else if eat_word(p, "tag") || eat_word(p, "enum") { ret some(parse_item_tag(p, attrs)); - } else if is_word(p, "obj") && p.look_ahead(1u) != token::LPAREN { - p.bump(); - ret some(parse_item_obj(p, attrs)); } else if eat_word(p, "iface") { ret some(parse_item_iface(p, attrs)); } else if eat_word(p, "impl") { diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index 50fb51986feb..6de712e14bec 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -306,12 +306,6 @@ fn print_type(s: ps, &&ty: @ast::ty) { ast::ty_fn(proto, d) { print_ty_fn(s, proto, d, none, none); } - ast::ty_obj(methods) { - head(s, "obj"); - bopen(s); - for m in methods { print_ty_method(s, m); } - bclose(s, ty.span); - } ast::ty_path(path, _) { print_path(s, path, false); } ast::ty_type. { word(s.s, "type"); } ast::ty_constr(t, cs) { @@ -438,32 +432,6 @@ fn print_item(s: ps, &&item: @ast::item) { bclose(s, item.span); } } - ast::item_obj(_obj, params, _) { - head(s, "obj"); - word(s.s, item.ident); - print_type_params(s, params); - popen(s); - fn print_field(s: ps, field: ast::obj_field) { - ibox(s, indent_unit); - print_mutability(s, field.mut); - word_space(s, field.ident + ":"); - print_type(s, field.ty); - end(s); - } - fn get_span(f: ast::obj_field) -> codemap::span { ret f.ty.span; } - commasep_cmnt(s, consistent, _obj.fields, print_field, get_span); - pclose(s); - space(s.s); - bopen(s); - for meth: @ast::method in _obj.methods { - hardbreak_if_not_bol(s); - maybe_print_comment(s, meth.span.lo); - print_fn(s, meth.decl, meth.ident, meth.tps); - word(s.s, " "); - print_block(s, meth.body); - } - bclose(s, item.span); - } ast::item_impl(tps, ifce, ty, methods) { head(s, "impl"); word(s.s, item.ident); @@ -972,50 +940,6 @@ fn print_expr(s: ps, &&expr: @ast::expr) { pclose(s); } ast::expr_mac(m) { print_mac(s, m); } - ast::expr_anon_obj(anon_obj) { - head(s, "obj"); - - // Fields - popen(s); - fn print_field(s: ps, field: ast::anon_obj_field) { - ibox(s, indent_unit); - print_mutability(s, field.mut); - word_space(s, field.ident + ":"); - print_type(s, field.ty); - space(s.s); - word_space(s, "="); - print_expr(s, field.expr); - end(s); - } - fn get_span(f: ast::anon_obj_field) -> codemap::span { - ret f.ty.span; - } - alt anon_obj.fields { - none. { } - some(fields) { - commasep_cmnt(s, consistent, fields, print_field, get_span); - } - } - pclose(s); - space(s.s); - bopen(s); - - // Methods - for meth: @ast::method in anon_obj.methods { - hardbreak_if_not_bol(s); - maybe_print_comment(s, meth.span.lo); - print_fn(s, meth.decl, meth.ident, meth.tps); - word(s.s, " "); - print_block(s, meth.body); - } - - // With object - alt anon_obj.inner_obj { - none. { } - some(e) { space(s.s); word_space(s, "with"); print_expr(s, e); } - } - bclose(s, expr.span); - } } s.ann.post(ann_node); end(s); diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs index 1c38095d519e..33233e9158f4 100644 --- a/src/comp/syntax/visit.rs +++ b/src/comp/syntax/visit.rs @@ -126,14 +126,6 @@ fn visit_item(i: @item, e: E, v: vt) { for va: variant_arg in vr.node.args { v.visit_ty(va.ty, e, v); } } } - item_obj(ob, tps, _) { - v.visit_ty_params(tps, e, v); - for f: obj_field in ob.fields { v.visit_ty(f.ty, e, v); } - for m: @method in ob.methods { - v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span, - m.id, e, v); - } - } item_impl(tps, ifce, ty, methods) { v.visit_ty_params(tps, e, v); alt ifce { some(ty) { v.visit_ty(ty, e, v); } _ {} } @@ -172,12 +164,6 @@ fn visit_ty(t: @ty, e: E, v: vt) { } v.visit_ty(decl.output, e, v); } - ty_obj(tmeths) { - for m: ty_method in tmeths { - for a in m.decl.inputs { v.visit_ty(a.ty, e, v); } - v.visit_ty(m.decl.output, e, v); - } - } ty_path(p, _) { visit_path(p, e, v); } ty_type. {/* no-op */ } ty_constr(t, cs) { @@ -370,25 +356,6 @@ fn visit_expr(ex: @expr, e: E, v: vt) { } expr_check(_, x) { v.visit_expr(x, e, v); } expr_assert(x) { v.visit_expr(x, e, v); } - expr_anon_obj(anon_obj) { - alt anon_obj.fields { - none. { } - some(fields) { - for f: anon_obj_field in fields { - v.visit_ty(f.ty, e, v); - v.visit_expr(f.expr, e, v); - } - } - } - alt anon_obj.inner_obj { - none. { } - some(ex) { v.visit_expr(ex, e, v); } - } - for m: @method in anon_obj.methods { - v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span, - m.id, e, v); - } - } expr_mac(mac) { visit_mac(mac, e, v); } } } diff --git a/src/comp/util/ppaux.rs b/src/comp/util/ppaux.rs index d4c01edbb15a..fe6dfc4fd8a1 100644 --- a/src/comp/util/ppaux.rs +++ b/src/comp/util/ppaux.rs @@ -112,11 +112,6 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { fn_to_str(cx, ast::proto_bare, none, inputs, output, ast::return_val, []) } - ty_obj(meths) { - let strs = []; - for m: method in meths { strs += [method_to_str(cx, m)]; } - "obj {\n\t" + str::connect(strs, "\n\t") + "\n}" - } ty_var(v) { "" } ty_param(id, _) { "'" + str::unsafe_from_bytes([('a' as u8) + (id as u8)])