Remove vestiges of typarams from anon objs.
This commit is contained in:
parent
f33309502a
commit
55acc737a8
10 changed files with 35 additions and 77 deletions
|
@ -5847,8 +5847,8 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ->
|
||||||
case (ast::expr_spawn(?dom, ?name, ?func, ?args)) {
|
case (ast::expr_spawn(?dom, ?name, ?func, ?args)) {
|
||||||
ret trans_spawn(cx, dom, name, func, args, e.id);
|
ret trans_spawn(cx, dom, name, func, args, e.id);
|
||||||
}
|
}
|
||||||
case (ast::expr_anon_obj(?anon_obj, ?tps)) {
|
case (ast::expr_anon_obj(?anon_obj)) {
|
||||||
ret trans_anon_obj(cx, e.span, anon_obj, tps, e.id);
|
ret trans_anon_obj(cx, e.span, anon_obj, e.id);
|
||||||
}
|
}
|
||||||
case (_) {
|
case (_) {
|
||||||
// The expression is an lvalue. Fall through.
|
// The expression is an lvalue. Fall through.
|
||||||
|
@ -6222,15 +6222,9 @@ fn trans_be(&@block_ctxt cx, &@ast::expr e) -> result {
|
||||||
// instead "inlining" the construction of the object and returning the object
|
// instead "inlining" the construction of the object and returning the object
|
||||||
// itself.
|
// itself.
|
||||||
fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
|
fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
|
||||||
&ast::ty_param[] ty_params, ast::node_id id) -> result {
|
ast::node_id id) -> result {
|
||||||
|
|
||||||
// Right now, we're assuming that anon objs don't take ty params, even
|
|
||||||
// though the AST supports it. It's nonsensical to write an expression
|
|
||||||
// like "obj[T](){ ... with ... }", since T is never instantiated;
|
|
||||||
// nevertheless, such an expression will parse. Idea for the future:
|
|
||||||
// support typarams.
|
|
||||||
|
|
||||||
assert (std::ivec::len(ty_params) == 0u);
|
|
||||||
auto ccx = bcx.fcx.lcx.ccx;
|
auto ccx = bcx.fcx.lcx.ccx;
|
||||||
|
|
||||||
// Fields.
|
// Fields.
|
||||||
|
@ -6286,7 +6280,7 @@ fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
|
||||||
// is that, since *all* of the methods are "additional", we can
|
// is that, since *all* of the methods are "additional", we can
|
||||||
// get away with acting like none of them are.
|
// get away with acting like none of them are.
|
||||||
vtbl = create_vtbl(bcx.fcx.lcx, sp, outer_obj_ty,
|
vtbl = create_vtbl(bcx.fcx.lcx, sp, outer_obj_ty,
|
||||||
wrapper_obj, ty_params, none,
|
wrapper_obj, ~[], none,
|
||||||
additional_field_tys);
|
additional_field_tys);
|
||||||
}
|
}
|
||||||
case (some(?e)) {
|
case (some(?e)) {
|
||||||
|
@ -6304,8 +6298,7 @@ fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
|
||||||
// create a forwarding slot. And, of course, we need to create a
|
// create a forwarding slot. And, of course, we need to create a
|
||||||
// normal vtable entry for every method being added.
|
// normal vtable entry for every method being added.
|
||||||
vtbl = create_vtbl(bcx.fcx.lcx, sp, outer_obj_ty,
|
vtbl = create_vtbl(bcx.fcx.lcx, sp, outer_obj_ty,
|
||||||
wrapper_obj, ty_params,
|
wrapper_obj, ~[], some(with_obj_ty),
|
||||||
some(with_obj_ty),
|
|
||||||
additional_field_tys);
|
additional_field_tys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6333,27 +6326,22 @@ fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
|
||||||
// typarams, fields, and a pointer to our with_obj.
|
// typarams, fields, and a pointer to our with_obj.
|
||||||
let TypeRef llbox_ty = T_ptr(T_empty_struct());
|
let TypeRef llbox_ty = T_ptr(T_empty_struct());
|
||||||
|
|
||||||
if (std::ivec::len[ast::ty_param](ty_params) == 0u &&
|
if (std::ivec::len[ast::anon_obj_field](additional_fields) == 0u &&
|
||||||
std::ivec::len[ast::anon_obj_field](additional_fields) == 0u &&
|
|
||||||
anon_obj.with_obj == none) {
|
anon_obj.with_obj == none) {
|
||||||
// If the object we're translating has no fields or type parameters
|
// If the object we're translating has no fields and no with_obj,
|
||||||
// and no with_obj, there's not much to do.
|
// there's not much to do.
|
||||||
bcx.build.Store(C_null(llbox_ty), pair_box);
|
bcx.build.Store(C_null(llbox_ty), pair_box);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Synthesize a tuple type for fields: [field, ...]
|
// Synthesize a tuple type for fields: [field, ...]
|
||||||
let ty::t fields_ty = ty::mk_imm_tup(ccx.tcx, additional_field_tys);
|
let ty::t fields_ty = ty::mk_imm_tup(ccx.tcx, additional_field_tys);
|
||||||
|
|
||||||
// Tydescs are run-time instantiations of typarams. We're not
|
// Type for tydescs.
|
||||||
// actually supporting typarams for anon objs yet, but let's
|
|
||||||
// create space for them in case we ever want them.
|
|
||||||
let ty::t tydesc_ty = ty::mk_type(ccx.tcx);
|
let ty::t tydesc_ty = ty::mk_type(ccx.tcx);
|
||||||
let ty::t[] tps = ~[];
|
|
||||||
for (ast::ty_param tp in ty_params) {
|
// Placeholder for non-existent typarams, since anon objs don't have
|
||||||
tps += ~[tydesc_ty];
|
// them.
|
||||||
}
|
let ty::t typarams_ty = ty::mk_imm_tup(ccx.tcx, ~[]);
|
||||||
// Synthesize a tuple type for typarams: [typaram, ...]
|
|
||||||
let ty::t typarams_ty = ty::mk_imm_tup(ccx.tcx, tps);
|
|
||||||
|
|
||||||
// Tuple type for body:
|
// Tuple type for body:
|
||||||
// [tydesc_ty, [typaram, ...], [field, ...], with_obj]
|
// [tydesc_ty, [typaram, ...], [field, ...], with_obj]
|
||||||
|
@ -6402,35 +6390,15 @@ fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
|
||||||
bcx = body_td.bcx;
|
bcx = body_td.bcx;
|
||||||
bcx.build.Store(body_td.val, body_tydesc.val);
|
bcx.build.Store(body_td.val, body_tydesc.val);
|
||||||
|
|
||||||
// Copy the object's type parameters and fields into the space we
|
// Copy the object's fields into the space we allocated for the object
|
||||||
// allocated for the object body. (This is something like saving the
|
// body. (This is something like saving the lexical environment of a
|
||||||
// lexical environment of a function in its closure: the "captured
|
// function in its closure: the fields were passed to the object
|
||||||
// typarams" are any type parameters that are passed to the object
|
// constructor and are now available to the object's methods.
|
||||||
// constructor and are then available to the object's methods.
|
|
||||||
// Likewise for the object's fields.)
|
|
||||||
|
|
||||||
// Copy typarams into captured typarams.
|
|
||||||
auto body_typarams =
|
|
||||||
GEP_tup_like(bcx, body_ty, body.val,
|
|
||||||
~[0, abi::obj_body_elt_typarams]);
|
|
||||||
bcx = body_typarams.bcx;
|
|
||||||
let int i = 0;
|
|
||||||
for (ast::ty_param tp in ty_params) {
|
|
||||||
auto typaram = bcx.fcx.lltydescs.(i);
|
|
||||||
auto capture =
|
|
||||||
GEP_tup_like(bcx, typarams_ty, body_typarams.val, ~[0, i]);
|
|
||||||
bcx = capture.bcx;
|
|
||||||
bcx = copy_val(bcx, INIT, capture.val, typaram,
|
|
||||||
tydesc_ty).bcx;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy additional fields into the object's body.
|
|
||||||
auto body_fields =
|
auto body_fields =
|
||||||
GEP_tup_like(bcx, body_ty, body.val,
|
GEP_tup_like(bcx, body_ty, body.val,
|
||||||
~[0, abi::obj_body_elt_fields]);
|
~[0, abi::obj_body_elt_fields]);
|
||||||
bcx = body_fields.bcx;
|
bcx = body_fields.bcx;
|
||||||
i = 0;
|
let int i = 0;
|
||||||
for (ast::anon_obj_field f in additional_fields) {
|
for (ast::anon_obj_field f in additional_fields) {
|
||||||
// FIXME (part of issue #538): make this work eventually, when we
|
// FIXME (part of issue #538): make this work eventually, when we
|
||||||
// have additional field exprs in the AST.
|
// have additional field exprs in the AST.
|
||||||
|
@ -7182,16 +7150,11 @@ fn process_fwding_mthd(@local_ctxt cx, &span sp, @ty::method m,
|
||||||
// Synthesize a tuple type for fields: [field, ...]
|
// Synthesize a tuple type for fields: [field, ...]
|
||||||
let ty::t fields_ty = ty::mk_imm_tup(cx.ccx.tcx, additional_field_tys);
|
let ty::t fields_ty = ty::mk_imm_tup(cx.ccx.tcx, additional_field_tys);
|
||||||
|
|
||||||
// Tydescs are run-time instantiations of typarams. We're not
|
// Type for tydescs.
|
||||||
// actually supporting typarams for anon objs yet, but let's
|
|
||||||
// create space for them in case we ever want them.
|
|
||||||
let ty::t tydesc_ty = ty::mk_type(cx.ccx.tcx);
|
let ty::t tydesc_ty = ty::mk_type(cx.ccx.tcx);
|
||||||
let ty::t[] tps = ~[];
|
|
||||||
for (ast::ty_param tp in ty_params) {
|
// Placeholder for non-existent typarams, since anon objs don't have them.
|
||||||
tps += ~[tydesc_ty];
|
let ty::t typarams_ty = ty::mk_imm_tup(cx.ccx.tcx, ~[]);
|
||||||
}
|
|
||||||
// Synthesize a tuple type for typarams: [typaram, ...]
|
|
||||||
let ty::t typarams_ty = ty::mk_imm_tup(cx.ccx.tcx, tps);
|
|
||||||
|
|
||||||
// Tuple type for body:
|
// Tuple type for body:
|
||||||
// [tydesc_ty, [typaram, ...], [field, ...], with_obj]
|
// [tydesc_ty, [typaram, ...], [field, ...], with_obj]
|
||||||
|
|
|
@ -567,7 +567,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
|
||||||
case (expr_mac(_)) {
|
case (expr_mac(_)) {
|
||||||
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
fcx.ccx.tcx.sess.bug("unexpanded macro");
|
||||||
}
|
}
|
||||||
case (expr_anon_obj(?anon_obj, _)) {
|
case (expr_anon_obj(?anon_obj)) {
|
||||||
alt (anon_obj.with_obj) {
|
alt (anon_obj.with_obj) {
|
||||||
case (some(?ex)) {
|
case (some(?ex)) {
|
||||||
find_pre_post_expr(fcx, ex);
|
find_pre_post_expr(fcx, ex);
|
||||||
|
|
|
@ -564,7 +564,7 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
|
||||||
case (expr_cont) { ret pure_exp(fcx.ccx, e.id, pres); }
|
case (expr_cont) { ret pure_exp(fcx.ccx, e.id, pres); }
|
||||||
case (expr_port(_)) { ret pure_exp(fcx.ccx, e.id, pres); }
|
case (expr_port(_)) { ret pure_exp(fcx.ccx, e.id, pres); }
|
||||||
case (expr_self_method(_)) { ret pure_exp(fcx.ccx, e.id, pres); }
|
case (expr_self_method(_)) { ret pure_exp(fcx.ccx, e.id, pres); }
|
||||||
case (expr_anon_obj(?anon_obj, _)) {
|
case (expr_anon_obj(?anon_obj)) {
|
||||||
alt (anon_obj.with_obj) {
|
alt (anon_obj.with_obj) {
|
||||||
case (some(?wt)) {
|
case (some(?wt)) {
|
||||||
ret find_pre_post_state_sub(fcx, pres, wt, e.id, none);
|
ret find_pre_post_state_sub(fcx, pres, wt, e.id, none);
|
||||||
|
|
|
@ -2395,7 +2395,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case (ast::expr_anon_obj(?ao, ?tps)) {
|
case (ast::expr_anon_obj(?ao)) {
|
||||||
|
|
||||||
let ast::anon_obj_field[] fields = ~[];
|
let ast::anon_obj_field[] fields = ~[];
|
||||||
alt (ao.fields) {
|
alt (ao.fields) {
|
||||||
|
@ -2432,8 +2432,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
|
||||||
|
|
||||||
fn get_anon_obj_method_types(@fn_ctxt fcx,
|
fn get_anon_obj_method_types(@fn_ctxt fcx,
|
||||||
&ast::anon_obj ao,
|
&ast::anon_obj ao,
|
||||||
&ast::anon_obj_field[] fields,
|
&ast::anon_obj_field[] fields)
|
||||||
&ast::ty_param[] tps)
|
|
||||||
-> ty::method[] {
|
-> ty::method[] {
|
||||||
|
|
||||||
let ty::method[] methods = ~[];
|
let ty::method[] methods = ~[];
|
||||||
|
@ -2495,7 +2494,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto method_types = get_anon_obj_method_types(fcx, ao,
|
auto method_types = get_anon_obj_method_types(fcx, ao,
|
||||||
fields, tps);
|
fields);
|
||||||
auto ot = ty::mk_obj(fcx.ccx.tcx, ty::sort_methods(method_types));
|
auto ot = ty::mk_obj(fcx.ccx.tcx, ty::sort_methods(method_types));
|
||||||
|
|
||||||
write::ty_only_fixup(fcx, id, ot);
|
write::ty_only_fixup(fcx, id, ot);
|
||||||
|
|
|
@ -325,7 +325,7 @@ tag expr_ {
|
||||||
expr_if_check(@expr, block, option::t[@expr]);
|
expr_if_check(@expr, block, option::t[@expr]);
|
||||||
expr_port(option::t[@ty]);
|
expr_port(option::t[@ty]);
|
||||||
expr_chan(@expr);
|
expr_chan(@expr);
|
||||||
expr_anon_obj(anon_obj, ty_param[]);
|
expr_anon_obj(anon_obj);
|
||||||
expr_mac(mac);
|
expr_mac(mac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -458,8 +458,8 @@ fn noop_fold_expr(&expr_ e, ast_fold fld) -> expr_ {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case (expr_chan(?e)) { expr_chan(fld.fold_expr(e)) }
|
case (expr_chan(?e)) { expr_chan(fld.fold_expr(e)) }
|
||||||
case (expr_anon_obj(?ao, ?typms)) {
|
case (expr_anon_obj(?ao)) {
|
||||||
expr_anon_obj(fold_anon_obj(ao), typms)
|
expr_anon_obj(fold_anon_obj(ao))
|
||||||
}
|
}
|
||||||
case (expr_mac(?mac)) {
|
case (expr_mac(?mac)) {
|
||||||
expr_mac(fold_mac(mac))
|
expr_mac(fold_mac(mac))
|
||||||
|
|
|
@ -833,9 +833,6 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
||||||
} else if (eat_word(p, "obj")) {
|
} else if (eat_word(p, "obj")) {
|
||||||
// Anonymous object
|
// Anonymous object
|
||||||
|
|
||||||
// FIXME: Can anonymous objects have ty params?
|
|
||||||
auto ty_params = parse_ty_params(p);
|
|
||||||
|
|
||||||
// Only make people type () if they're actually adding new fields
|
// Only make people type () if they're actually adding new fields
|
||||||
let option::t[ast::anon_obj_field[]] fields = none;
|
let option::t[ast::anon_obj_field[]] fields = none;
|
||||||
if (p.peek() == token::LPAREN) {
|
if (p.peek() == token::LPAREN) {
|
||||||
|
@ -864,7 +861,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
|
||||||
// "spanned".
|
// "spanned".
|
||||||
let ast::anon_obj ob =
|
let ast::anon_obj ob =
|
||||||
rec(fields=fields, methods=meths, with_obj=with_obj);
|
rec(fields=fields, methods=meths, with_obj=with_obj);
|
||||||
ex = ast::expr_anon_obj(ob, ty_params);
|
ex = ast::expr_anon_obj(ob);
|
||||||
} else if (eat_word(p, "rec")) {
|
} else if (eat_word(p, "rec")) {
|
||||||
expect(p, token::LPAREN);
|
expect(p, token::LPAREN);
|
||||||
auto fields = ~[parse_field(p)];
|
auto fields = ~[parse_field(p)];
|
||||||
|
@ -1686,7 +1683,7 @@ fn stmt_ends_with_semi(&ast::stmt stmt) -> bool {
|
||||||
case (ast::expr_if_check(_, _, _)) { false }
|
case (ast::expr_if_check(_, _, _)) { false }
|
||||||
case (ast::expr_port(_)) { true }
|
case (ast::expr_port(_)) { true }
|
||||||
case (ast::expr_chan(_)) { true }
|
case (ast::expr_chan(_)) { true }
|
||||||
case (ast::expr_anon_obj(_,_)) { false }
|
case (ast::expr_anon_obj(_)) { false }
|
||||||
case (ast::expr_assert(_)) { true }
|
case (ast::expr_assert(_)) { true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -986,9 +986,8 @@ fn print_expr(&ps s, &@ast::expr expr) {
|
||||||
print_expr(s, expr);
|
print_expr(s, expr);
|
||||||
pclose(s);
|
pclose(s);
|
||||||
}
|
}
|
||||||
case (ast::expr_anon_obj(?anon_obj, ?tps)) {
|
case (ast::expr_anon_obj(?anon_obj)) {
|
||||||
head(s, "obj");
|
head(s, "obj");
|
||||||
print_type_params(s, tps);
|
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
popen(s);
|
popen(s);
|
||||||
|
|
|
@ -395,7 +395,7 @@ fn visit_expr[E](&@expr ex, &E e, &vt[E] v) {
|
||||||
case (expr_assert(?x)) { v.visit_expr(x, e, v); }
|
case (expr_assert(?x)) { v.visit_expr(x, e, v); }
|
||||||
case (expr_port(?t)) { visit_ty_opt(t, e, v); }
|
case (expr_port(?t)) { visit_ty_opt(t, e, v); }
|
||||||
case (expr_chan(?x)) { v.visit_expr(x, e, v); }
|
case (expr_chan(?x)) { v.visit_expr(x, e, v); }
|
||||||
case (expr_anon_obj(?anon_obj, _)) {
|
case (expr_anon_obj(?anon_obj)) {
|
||||||
alt (anon_obj.fields) {
|
alt (anon_obj.fields) {
|
||||||
case (none) { }
|
case (none) { }
|
||||||
case (some(?fields)) {
|
case (some(?fields)) {
|
||||||
|
|
|
@ -388,7 +388,7 @@ fn walk_expr(&ast_visitor v, @ast::expr e) {
|
||||||
case (ast::expr_assert(?x)) { walk_expr(v, x); }
|
case (ast::expr_assert(?x)) { walk_expr(v, x); }
|
||||||
case (ast::expr_port(_)) { }
|
case (ast::expr_port(_)) { }
|
||||||
case (ast::expr_chan(?x)) { walk_expr(v, x); }
|
case (ast::expr_chan(?x)) { walk_expr(v, x); }
|
||||||
case (ast::expr_anon_obj(?anon_obj, _)) {
|
case (ast::expr_anon_obj(?anon_obj)) {
|
||||||
// Fields
|
// Fields
|
||||||
|
|
||||||
alt (anon_obj.fields) {
|
alt (anon_obj.fields) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue