Skip to content

Commit 0547d0c

Browse files
committed
Monomorphize resource and variant constructors
Issue #1736
1 parent 7c8d128 commit 0547d0c

File tree

4 files changed

+87
-76
lines changed

4 files changed

+87
-76
lines changed

src/comp/middle/ast_map.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ enum ast_node {
1111
node_item(@item, @path),
1212
node_native_item(@native_item, @path),
1313
node_method(@method, @path),
14+
node_variant(variant, def_id, @path),
1415
node_expr(@expr),
1516
// Locals are numbered, because the alias analysis needs to know in which
1617
// order they are introduced.
@@ -74,6 +75,13 @@ fn map_item(i: @item, cx: ctx, v: vt) {
7475
cx.map.insert(ctor_id, node_res_ctor(i));
7576
cx.map.insert(dtor_id, node_item(i, @cx.path));
7677
}
78+
item_enum(vs, _) {
79+
for v in vs {
80+
cx.map.insert(v.node.id, node_variant(
81+
v, ast_util::local_def(i.id),
82+
@(cx.path + [path_name(i.ident)])));
83+
}
84+
}
7785
_ { }
7886
}
7987
alt i.node {

src/comp/middle/trans/base.rs

Lines changed: 75 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,7 +2429,7 @@ fn trans_external_path(cx: @block_ctxt, did: ast::def_id,
24292429

24302430
fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
24312431
dicts: option<typeck::dict_res>)
2432-
-> {llfn: ValueRef, fty: ty::t} {
2432+
-> option<{llfn: ValueRef, fty: ty::t}> {
24332433
let substs = vec::map(substs, {|t|
24342434
alt ty::get(t).struct {
24352435
ty::ty_box(mt) {
@@ -2447,29 +2447,47 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
24472447
none { [] }
24482448
}};
24492449
alt ccx.monomorphized.find(hash_id) {
2450-
some(val) { ret val; }
2450+
some(val) { ret some(val); }
24512451
none {}
24522452
}
24532453
let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
24542454
let mono_ty = ty::substitute_type_params(ccx.tcx, substs, tpt.ty);
2455-
let (item, pt) = alt ccx.tcx.items.get(fn_id.node) {
2456-
ast_map::node_item(i, p) { (i, p) } _ { fail; }
2457-
};
2458-
let pt = *pt + [path_name(item.ident)];
2459-
let result = alt item.node {
2460-
ast::item_fn(decl, _, body) {
2461-
let llfty = type_of_fn_from_ty(ccx, mono_ty, []);
2455+
let llfty = type_of_fn_from_ty(ccx, mono_ty, []);
2456+
let lldecl;
2457+
alt ccx.tcx.items.get(fn_id.node) {
2458+
ast_map::node_item(item, pt) {
2459+
let pt = *pt + [path_name(item.ident)];
2460+
let s = mangle_exported_name(ccx, pt, mono_ty);
2461+
lldecl = decl_cdecl_fn(ccx.llmod, s, llfty);
2462+
alt item.node {
2463+
ast::item_fn(decl, _, body) {
2464+
trans_fn(ccx, pt, decl, body, lldecl, no_self, [],
2465+
some(substs), fn_id.node);
2466+
}
2467+
ast::item_res(decl, _, _, _, ctor_id) {
2468+
trans_res_ctor(ccx, pt, decl, ctor_id, [], some(substs), lldecl);
2469+
}
2470+
_ { fail "Unexpected item type"; }
2471+
}
2472+
}
2473+
ast_map::node_variant(v, enum_id, pt) {
2474+
let pt = *pt + [path_name(v.node.name)];
24622475
let s = mangle_exported_name(ccx, pt, mono_ty);
2463-
let lldecl = decl_cdecl_fn(ccx.llmod, s, llfty);
2464-
trans_fn(ccx, pt, decl, body, lldecl, no_self, [],
2465-
some(substs), fn_id.node);
2466-
lldecl
2476+
lldecl = decl_cdecl_fn(ccx.llmod, s, llfty);
2477+
let tvs = ty::enum_variants(ccx.tcx, enum_id);
2478+
let this_tv = option::get(vec::find(*tvs, {|tv|
2479+
tv.id.node == fn_id.node}));
2480+
trans_enum_variant(ccx, enum_id.node, v, this_tv.disr_val,
2481+
vec::len(*tvs) == 1u, [], some(substs), lldecl);
24672482
}
2468-
_ { fail "FIXME[mono] handle other constructs"; }
2469-
};
2470-
let val = {llfn: result, fty: mono_ty};
2483+
ast_map::node_native_item(_, _) {
2484+
ret none;
2485+
}
2486+
_ { fail "Unexpected node type"; }
2487+
}
2488+
let val = {llfn: lldecl, fty: mono_ty};
24712489
ccx.monomorphized.insert(hash_id, val);
2472-
val
2490+
some(val)
24732491
}
24742492

24752493
fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
@@ -2484,10 +2502,14 @@ fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
24842502
alt b { ty::bound_iface(_) { false } _ { true } }
24852503
})}) {
24862504
let dicts = ccx.dict_map.find(id);
2487-
let {llfn, fty} = monomorphic_fn(ccx, fn_id, tys, dicts);
2488-
ret {bcx: bcx, val: llfn,
2489-
kind: owned, env: null_env,
2490-
generic: generic_mono(fty)};
2505+
alt monomorphic_fn(ccx, fn_id, tys, dicts) {
2506+
some({llfn, fty}) {
2507+
ret {bcx: bcx, val: llfn,
2508+
kind: owned, env: null_env,
2509+
generic: generic_mono(fty)};
2510+
}
2511+
none {}
2512+
}
24912513
}
24922514
let val = if fn_id.crate == ast::local_crate {
24932515
// Internal reference.
@@ -4362,15 +4384,6 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
43624384
ret bcx;
43634385
}
43644386

4365-
fn arg_tys_of_fn(ccx: @crate_ctxt, id: ast::node_id) -> [ty::arg] {
4366-
let tt = ty::node_id_to_type(ccx.tcx, id);
4367-
alt ty::get(tt).struct {
4368-
ty::ty_fn({inputs, _}) { inputs }
4369-
_ { ccx.sess.bug(#fmt("arg_tys_of_fn called on non-function\
4370-
type %s", ty_to_str(ccx.tcx, tt)));}
4371-
}
4372-
}
4373-
43744387
// Ties up the llstaticallocas -> llloadenv -> llderivedtydescs ->
43754388
// lldynamicallocas -> lltop edges, and builds the return block.
43764389
fn finish_fn(fcx: @fn_ctxt, lltop: BasicBlockRef) {
@@ -4407,7 +4420,7 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
44074420
let lltop = bcx.llbb;
44084421
let block_ty = node_id_type(bcx, body.node.id);
44094422

4410-
let arg_tys = arg_tys_of_fn(fcx.ccx, id);
4423+
let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
44114424
alt param_substs {
44124425
some(ts) {
44134426
arg_tys = vec::map(arg_tys, {|a|
@@ -4459,23 +4472,23 @@ fn trans_fn(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
44594472
}
44604473

44614474
fn trans_res_ctor(ccx: @crate_ctxt, path: path, dtor: ast::fn_decl,
4462-
ctor_id: ast::node_id, ty_params: [ast::ty_param]) {
4475+
ctor_id: ast::node_id, ty_params: [ast::ty_param],
4476+
param_substs: option<[ty::t]>, llfndecl: ValueRef) {
44634477
// Create a function for the constructor
4464-
let llctor_decl = ccx.item_ids.get(ctor_id);
4465-
let fcx = new_fn_ctxt_w_id(ccx, path, llctor_decl, ctor_id, none, none);
4466-
let ret_t = ty::ret_ty_of_fn(ccx.tcx, ctor_id);
4478+
let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, ctor_id,
4479+
param_substs, none);
44674480
create_llargs_for_fn_args(fcx, no_self, dtor.inputs, ty_params);
4468-
let bcx = new_top_block_ctxt(fcx, none);
4469-
let lltop = bcx.llbb;
4470-
let arg_t = arg_tys_of_fn(ccx, ctor_id)[0].ty;
4481+
let bcx = new_top_block_ctxt(fcx, none), lltop = bcx.llbb;
4482+
let fty = node_id_type(bcx, ctor_id);
4483+
let arg_t = ty::ty_fn_args(fty)[0].ty;
44714484
let tup_t = ty::mk_tup(ccx.tcx, [ty::mk_int(ccx.tcx), arg_t]);
44724485
let arg = alt fcx.llargs.find(dtor.inputs[0].id) {
44734486
some(local_mem(x)) { x }
44744487
_ { ccx.sess.bug("Someone forgot to document an invariant \
44754488
in trans_res_ctor"); }
44764489
};
44774490
let llretptr = fcx.llretptr;
4478-
if ty::type_has_dynamic_size(ccx.tcx, ret_t) {
4491+
if ty::type_has_dynamic_size(ccx.tcx, ty::ty_fn_ret(fty)) {
44794492
let llret_t = T_ptr(T_struct([ccx.int_type, llvm::LLVMTypeOf(arg)]));
44804493
llretptr = BitCast(bcx, llretptr, llret_t);
44814494
}
@@ -4495,11 +4508,8 @@ fn trans_res_ctor(ccx: @crate_ctxt, path: path, dtor: ast::fn_decl,
44954508
fn trans_enum_variant(ccx: @crate_ctxt,
44964509
enum_id: ast::node_id,
44974510
variant: ast::variant, disr: int, is_degen: bool,
4498-
ty_params: [ast::ty_param]) {
4499-
if vec::len(variant.node.args) == 0u {
4500-
ret; // nullary constructors are just constants
4501-
}
4502-
4511+
ty_params: [ast::ty_param],
4512+
param_substs: option<[ty::t]>, llfndecl: ValueRef) {
45034513
// Translate variant arguments to function arguments.
45044514
let fn_args = [], i = 0u;
45054515
for varg in variant.node.args {
@@ -4508,27 +4518,21 @@ fn trans_enum_variant(ccx: @crate_ctxt,
45084518
ident: "arg" + uint::to_str(i, 10u),
45094519
id: varg.id}];
45104520
}
4511-
assert (ccx.item_ids.contains_key(variant.node.id));
4512-
let llfndecl: ValueRef;
4513-
alt ccx.item_ids.find(variant.node.id) {
4514-
some(x) { llfndecl = x; }
4515-
_ {
4516-
ccx.sess.span_fatal(variant.span,
4517-
"unbound variant id in trans_enum_variant");
4518-
}
4519-
}
4520-
let fcx = new_fn_ctxt_w_id(ccx, [], llfndecl, variant.node.id, none,
4521-
none);
4521+
let fcx = new_fn_ctxt_w_id(ccx, [], llfndecl, variant.node.id,
4522+
param_substs, none);
45224523
create_llargs_for_fn_args(fcx, no_self, fn_args, ty_params);
4523-
let ty_param_substs = [], i = 0u;
4524-
for tp: ast::ty_param in ty_params {
4525-
ty_param_substs += [ty::mk_param(ccx.tcx, i,
4526-
local_def(tp.id))];
4527-
i += 1u;
4528-
}
4529-
let arg_tys = arg_tys_of_fn(ccx, variant.node.id);
4530-
let bcx = new_top_block_ctxt(fcx, none);
4531-
let lltop = bcx.llbb;
4524+
let ty_param_substs = alt param_substs {
4525+
some(ts) { ts }
4526+
none {
4527+
let i = 0u;
4528+
vec::map(ty_params, {|tp|
4529+
i += 1u;
4530+
ty::mk_param(ccx.tcx, i - 1u, local_def(tp.id))
4531+
})
4532+
}
4533+
};
4534+
let bcx = new_top_block_ctxt(fcx, none), lltop = bcx.llbb;
4535+
let arg_tys = ty::ty_fn_args(node_id_type(bcx, variant.node.id));
45324536
bcx = copy_args_to_allocas(fcx, bcx, fn_args, arg_tys);
45334537

45344538
// Cast the enum to a type we can GEP into.
@@ -4852,7 +4856,8 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
48524856
impl::trans_impl(ccx, *path, item.ident, ms, item.id, tps);
48534857
}
48544858
ast::item_res(decl, tps, body, dtor_id, ctor_id) {
4855-
trans_res_ctor(ccx, *path, decl, ctor_id, tps);
4859+
let llctor_decl = ccx.item_ids.get(ctor_id);
4860+
trans_res_ctor(ccx, *path, decl, ctor_id, tps, none, llctor_decl);
48564861

48574862
// Create a function for the destructor
48584863
alt ccx.item_ids.find(item.id) {
@@ -4873,8 +4878,11 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
48734878
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
48744879
let i = 0;
48754880
for variant: ast::variant in variants {
4876-
trans_enum_variant(ccx, item.id, variant,
4877-
vi[i].disr_val, degen, tps);
4881+
if vec::len(variant.node.args) > 0u {
4882+
trans_enum_variant(ccx, item.id, variant,
4883+
vi[i].disr_val, degen, tps,
4884+
none, ccx.item_ids.get(variant.node.id));
4885+
}
48784886
i += 1;
48794887
}
48804888
}

src/comp/middle/tstate/ck.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import syntax::ast;
33
import ast::{stmt, fn_ident, node_id, crate, return_val, noreturn, expr};
44
import syntax::{visit, print};
55
import syntax::codemap::span;
6-
import middle::ty::{type_is_nil, ret_ty_of_fn};
7-
import tstate::ann::{
8-
precond, prestate,
6+
import middle::ty;
7+
import tstate::ann::{precond, prestate,
98
implies, ann_precond, ann_prestate};
109
import option;
1110
import aux::*;
@@ -113,7 +112,8 @@ fn check_states_against_conditions(fcx: fn_ctxt,
113112
/* Check that the return value is initialized */
114113
let post = aux::block_poststate(fcx.ccx, f_body);
115114
if !promises(fcx, post, fcx.enclosing.i_return) &&
116-
!type_is_nil(ret_ty_of_fn(fcx.ccx.tcx, id)) &&
115+
!ty::type_is_nil(ty::ty_fn_ret(ty::node_id_to_type(
116+
fcx.ccx.tcx, id))) &&
117117
f_decl.cf == return_val {
118118
fcx.ccx.tcx.sess.span_err(f_body.span,
119119
"In function " + fcx.name +

src/comp/middle/ty.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ export mk_named, type_name;
5353
export mt;
5454
export node_type_table;
5555
export pat_ty;
56-
export ret_ty_of_fn;
5756
export sequence_element_type;
5857
export sort_methods;
5958
export stmt_node_id;
@@ -2429,10 +2428,6 @@ fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_bounds_and_ty {
24292428
}
24302429
}
24312430

2432-
fn ret_ty_of_fn(cx: ctxt, id: ast::node_id) -> t {
2433-
ty_fn_ret(node_id_to_type(cx, id))
2434-
}
2435-
24362431
fn is_binopable(_cx: ctxt, ty: t, op: ast::binop) -> bool {
24372432
const tycat_other: int = 0;
24382433
const tycat_bool: int = 1;

0 commit comments

Comments
 (0)