Skip to content

Commit 02082be

Browse files
committed
Fix various bugs in monomorphization
Enough to be able to compile librustc with --monomorphize. Issue #1736
1 parent 52a7417 commit 02082be

File tree

8 files changed

+81
-64
lines changed

8 files changed

+81
-64
lines changed

src/comp/middle/alias.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ fn pattern_roots(tcx: ty::ctxt, mut: option<unsafe_ty>, pat: @ast::pat)
615615
ast::pat_rec(fs, _) {
616616
let ty = ty::node_id_to_type(tcx, pat.id);
617617
for f in fs {
618-
let m = ty::get_field(tcx, ty, f.ident).mt.mut != ast::imm,
618+
let m = ty::get_field(ty, f.ident).mt.mut != ast::imm,
619619
c = if m { some(contains(ty)) } else { mut };
620620
walk(tcx, c, f.pat, set);
621621
}

src/comp/middle/debuginfo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ fn create_record(cx: @crate_ctxt, t: ty::t, fields: [ast::ty_field],
411411
line_from_span(cx.sess.codemap,
412412
span) as int);
413413
for field in fields {
414-
let field_t = ty::get_field(ccx_tcx(cx), t, field.node.ident).mt.ty;
414+
let field_t = ty::get_field(t, field.node.ident).mt.ty;
415415
let ty_md = create_ty(cx, field_t, field.node.mt.ty);
416416
let (size, align) = member_size_and_align(cx.tcx, field.node.mt.ty);
417417
add_member(scx, field.node.ident,

src/comp/middle/trans/alt.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id,
265265
let ccx = bcx.fcx.ccx, bcx = bcx;
266266
// invariant:
267267
// pat_id must have the same length ty_param_substs as vdefs?
268-
let ty_param_substs = ty::node_id_to_type_params(ccx.tcx, pat_id);
268+
let ty_param_substs = node_id_type_params(bcx, pat_id);
269269
let blobptr = val;
270270
let variants = ty::enum_variants(ccx.tcx, vdefs.enm);
271271
let args = [];
@@ -420,8 +420,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
420420
let rec_fields = collect_record_fields(m, col);
421421
// Separate path for extracting and binding record fields
422422
if vec::len(rec_fields) > 0u {
423-
let rec_ty = ty::node_id_to_type(ccx.tcx, pat_id);
424-
let fields = ty::get_fields(ccx.tcx, rec_ty);
423+
let rec_ty = node_id_type(bcx, pat_id);
424+
let fields = ty::get_fields(rec_ty);
425425
let rec_vals = [];
426426
for field_name: ast::ident in rec_fields {
427427
let ix = option::get(ty::field_idx(field_name, fields));
@@ -435,7 +435,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
435435
}
436436

437437
if any_tup_pat(m, col) {
438-
let tup_ty = ty::node_id_to_type(ccx.tcx, pat_id);
438+
let tup_ty = node_id_type(bcx, pat_id);
439439
let n_tup_elts = alt ty::get(tup_ty).struct {
440440
ty::ty_tup(elts) { vec::len(elts) }
441441
_ { ccx.sess.bug("Non-tuple type in tuple pattern"); }
@@ -488,7 +488,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
488488
}
489489
lit(l) {
490490
test_val = Load(bcx, val);
491-
let pty = ty::node_id_to_type(ccx.tcx, pat_id);
491+
let pty = node_id_type(bcx, pat_id);
492492
kind = if ty::type_is_integral(pty) { switch }
493493
else { compare };
494494
}
@@ -539,7 +539,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
539539
let compare_cx = new_scope_block_ctxt(bcx, "compare_scope");
540540
Br(bcx, compare_cx.llbb);
541541
bcx = compare_cx;
542-
let t = ty::node_id_to_type(ccx.tcx, pat_id);
542+
let t = node_id_type(bcx, pat_id);
543543
let res = trans_opt(bcx, opt);
544544
alt res {
545545
single_result(r) {
@@ -622,7 +622,7 @@ fn make_phi_bindings(bcx: @block_ctxt, map: [exit_node],
622622
forgot to document an invariant in \
623623
make_phi_bindings"); }
624624
};
625-
let e_ty = ty::node_id_to_type(bcx_tcx(bcx), node_id);
625+
let e_ty = node_id_type(bcx, node_id);
626626
let {bcx: abcx, val: alloc} = base::alloc_ty(bcx, e_ty);
627627
bcx = base::copy_val(abcx, base::INIT, alloc,
628628
load_if_immediate(abcx, local, e_ty),
@@ -739,7 +739,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
739739
}
740740
ast::pat_rec(fields, _) {
741741
let rec_ty = node_id_type(bcx, pat.id);
742-
let rec_fields = ty::get_fields(ccx.tcx, rec_ty);
742+
let rec_fields = ty::get_fields(rec_ty);
743743
for f: ast::field_pat in fields {
744744
let ix = option::get(ty::field_idx(f.ident, rec_fields));
745745
// how to get rid of this check?

src/comp/middle/trans/base.rs

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,7 +1902,7 @@ fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr,
19021902
alt bcx_ccx(bcx).method_map.find(un_expr.id) {
19031903
some(origin) {
19041904
let callee_id = ast_util::op_expr_callee_id(un_expr);
1905-
let fty = ty::node_id_to_type(bcx_tcx(bcx), callee_id);
1905+
let fty = node_id_type(bcx, callee_id);
19061906
ret trans_call_inner(bcx, fty, {|bcx|
19071907
impl::trans_method_callee(bcx, callee_id, e, origin)
19081908
}, [], un_expr.id, dest);
@@ -2036,7 +2036,6 @@ fn trans_eager_binop(cx: @block_ctxt, op: ast::binop, lhs: ValueRef,
20362036

20372037
fn trans_assign_op(bcx: @block_ctxt, ex: @ast::expr, op: ast::binop,
20382038
dst: @ast::expr, src: @ast::expr) -> @block_ctxt {
2039-
let tcx = bcx_tcx(bcx);
20402039
let t = expr_ty(bcx, src);
20412040
let lhs_res = trans_lval(bcx, dst);
20422041
assert (lhs_res.kind == owned);
@@ -2045,7 +2044,7 @@ fn trans_assign_op(bcx: @block_ctxt, ex: @ast::expr, op: ast::binop,
20452044
alt bcx_ccx(bcx).method_map.find(ex.id) {
20462045
some(origin) {
20472046
let callee_id = ast_util::op_expr_callee_id(ex);
2048-
let fty = ty::node_id_to_type(tcx, callee_id);
2047+
let fty = node_id_type(bcx, callee_id);
20492048
ret trans_call_inner(bcx, fty, {|bcx|
20502049
// FIXME provide the already-computed address, not the expr
20512050
impl::trans_method_callee(bcx, callee_id, dst, origin)
@@ -2169,7 +2168,7 @@ fn trans_binary(bcx: @block_ctxt, op: ast::binop, lhs: @ast::expr,
21692168
alt bcx_ccx(bcx).method_map.find(ex.id) {
21702169
some(origin) {
21712170
let callee_id = ast_util::op_expr_callee_id(ex);
2172-
let fty = ty::node_id_to_type(bcx_tcx(bcx), callee_id);
2171+
let fty = node_id_type(bcx, callee_id);
21732172
ret trans_call_inner(bcx, fty, {|bcx|
21742173
impl::trans_method_callee(bcx, callee_id, lhs, origin)
21752174
}, [rhs], ex.id, dest);
@@ -2452,59 +2451,58 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
24522451
let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
24532452
let mono_ty = ty::substitute_type_params(ccx.tcx, substs, tpt.ty);
24542453
let llfty = type_of_fn_from_ty(ccx, mono_ty, []);
2455-
let lldecl;
2454+
2455+
let map_node = ccx.tcx.items.get(fn_id.node);
2456+
// Get the path so that we can create a symbol
2457+
let (pt, name) = alt map_node {
2458+
ast_map::node_item(i, pt) { (pt, i.ident) }
2459+
ast_map::node_variant(v, _, pt) { (pt, v.node.name) }
2460+
ast_map::node_method(m, _, pt) { (pt, m.ident) }
2461+
// We can't monomorphize native functions
2462+
ast_map::node_native_item(_, _) { ret none; }
2463+
_ { fail "Unexpected node type"; }
2464+
};
2465+
let pt = *pt + [path_name(ccx.names(name))];
2466+
let s = mangle_exported_name(ccx, pt, mono_ty);
2467+
let lldecl = decl_cdecl_fn(ccx.llmod, s, llfty);
2468+
ccx.monomorphized.insert(hash_id, {llfn: lldecl, fty: mono_ty});
2469+
24562470
let psubsts = some({tys: substs, dicts: dicts, bounds: tpt.bounds});
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-
psubsts, fn_id.node);
2466-
}
2467-
ast::item_res(decl, _, _, _, ctor_id) {
2468-
trans_res_ctor(ccx, pt, decl, ctor_id, [], psubsts, lldecl);
2469-
}
2470-
_ { fail "Unexpected item type"; }
2471-
}
2471+
alt map_node {
2472+
ast_map::node_item(@{node: ast::item_fn(decl, _, body), _}, _) {
2473+
trans_fn(ccx, pt, decl, body, lldecl, no_self, [],
2474+
psubsts, fn_id.node);
2475+
}
2476+
ast_map::node_item(@{node: ast::item_res(decl, _, _, _, _), _}, _) {
2477+
trans_res_ctor(ccx, pt, decl, fn_id.node, [], psubsts, lldecl);
24722478
}
2473-
ast_map::node_variant(v, enum_id, pt) {
2474-
let pt = *pt + [path_name(v.node.name)];
2475-
let s = mangle_exported_name(ccx, pt, mono_ty);
2476-
lldecl = decl_cdecl_fn(ccx.llmod, s, llfty);
2479+
ast_map::node_variant(v, enum_id, _) {
24772480
let tvs = ty::enum_variants(ccx.tcx, enum_id);
24782481
let this_tv = option::get(vec::find(*tvs, {|tv|
24792482
tv.id.node == fn_id.node}));
24802483
trans_enum_variant(ccx, enum_id.node, v, this_tv.disr_val,
24812484
vec::len(*tvs) == 1u, [], psubsts, lldecl);
24822485
}
2483-
ast_map::node_method(mth, impl_id, pt) {
2484-
let pt = *pt + [path_name(mth.ident)];
2485-
let s = mangle_exported_name(ccx, pt, mono_ty);
2486-
lldecl = decl_cdecl_fn(ccx.llmod, s, llfty);
2486+
ast_map::node_method(mth, impl_id, _) {
24872487
let selfty = ty::node_id_to_type(ccx.tcx, impl_id);
24882488
let selfty = ty::substitute_type_params(ccx.tcx, substs, selfty);
24892489
trans_fn(ccx, pt, mth.decl, mth.body, lldecl,
24902490
impl_self(selfty), [], psubsts, fn_id.node);
24912491
}
2492-
ast_map::node_native_item(_, _) {
2493-
ret none;
2494-
}
2495-
_ { fail "Unexpected node type"; }
2492+
_ { fail; }
24962493
}
2497-
let val = {llfn: lldecl, fty: mono_ty};
2498-
ccx.monomorphized.insert(hash_id, val);
2499-
some(val)
2494+
some({llfn: lldecl, fty: mono_ty})
25002495
}
25012496

25022497
fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id,
25032498
substs: option<([ty::t], typeck::dict_res)>)
25042499
-> lval_maybe_callee {
25052500
let ccx = bcx_ccx(bcx);
2506-
let tys = ty::node_id_to_type_params(ccx.tcx, id);
2501+
let tys = node_id_type_params(bcx, id);
25072502
let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
2503+
// The awkwardness below mostly stems from the fact that we're mixing
2504+
// monomorphized and non-monomorphized functions at the moment. If
2505+
// monomorphizing becomes the only approach, this'll be much simpler.
25082506
if ccx.sess.opts.monomorphize &&
25092507
(option::is_some(substs) || vec::len(tys) > 0u) &&
25102508
fn_id.crate == ast::local_crate &&
@@ -2634,7 +2632,7 @@ fn trans_var(cx: @block_ctxt, def: ast::def, id: ast::node_id)
26342632
ret lval_static_fn(cx, vid, id, none);
26352633
} else {
26362634
// Nullary variant.
2637-
let enum_ty = ty::node_id_to_type(ccx.tcx, id);
2635+
let enum_ty = node_id_type(cx, id);
26382636
let alloc_result = alloc_ty(cx, enum_ty);
26392637
let llenumblob = alloc_result.val;
26402638
let llenumty = type_of_enum(ccx, tid, enum_ty);
@@ -2652,7 +2650,7 @@ fn trans_var(cx: @block_ctxt, def: ast::def, id: ast::node_id)
26522650
assert (ccx.consts.contains_key(did.node));
26532651
ret lval_no_env(cx, ccx.consts.get(did.node), owned);
26542652
} else {
2655-
let tp = ty::node_id_to_type(ccx.tcx, id);
2653+
let tp = node_id_type(cx, id);
26562654
let val = trans_external_path(cx, did, {bounds: @[], ty: tp});
26572655
ret lval_no_env(cx, load_if_immediate(cx, val, tp), owned_imm);
26582656
}
@@ -3129,8 +3127,6 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t,
31293127
// NB: 'f' isn't necessarily a function; it might be an entire self-call
31303128
// expression because of the hack that allows us to process self-calls
31313129
// with trans_call.
3132-
let tcx = bcx_tcx(in_cx);
3133-
31343130
let cx = new_scope_block_ctxt(in_cx, "call");
31353131
Br(in_cx, cx.llbb);
31363132
let f_res = get_callee(cx);
@@ -3157,7 +3153,7 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t,
31573153
}
31583154
}
31593155

3160-
let ret_ty = ty::node_id_to_type(tcx, id);
3156+
let ret_ty = node_id_type(bcx, id);
31613157
let args_res =
31623158
trans_args(bcx, llenv, f_res.generic, args, fn_expr_ty, dest);
31633159
bcx = args_res.bcx;
@@ -3520,7 +3516,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
35203516
// If it is here, it's not an lval, so this is a user-defined index op
35213517
let origin = bcx_ccx(bcx).method_map.get(e.id);
35223518
let callee_id = ast_util::op_expr_callee_id(e);
3523-
let fty = ty::node_id_to_type(tcx, callee_id);
3519+
let fty = node_id_type(bcx, callee_id);
35243520
ret trans_call_inner(bcx, fty, {|bcx|
35253521
impl::trans_method_callee(bcx, callee_id, base, origin)
35263522
}, [idx], e.id, dest);

src/comp/middle/trans/closure.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import back::link::{
1616
import util::ppaux::ty_to_str;
1717
import shape::{size_of};
1818
import ast_map::{path, path_mod, path_name};
19+
import driver::session::session;
1920

2021
// ___Good to know (tm)__________________________________________________
2122
//
@@ -362,7 +363,7 @@ fn build_closure(bcx0: @block_ctxt,
362363
vec::iter(cap_vars) { |cap_var|
363364
let lv = trans_local_var(bcx, cap_var.def);
364365
let nid = ast_util::def_id_of_def(cap_var.def).node;
365-
let ty = ty::node_id_to_type(tcx, nid);
366+
let ty = node_id_type(bcx, nid);
366367
alt cap_var.mode {
367368
capture::cap_ref {
368369
assert ck == ty::ck_block;
@@ -486,7 +487,7 @@ fn trans_bind(cx: @block_ctxt, f: @ast::expr, args: [option<@ast::expr>],
486487
id: ast::node_id, dest: dest) -> @block_ctxt {
487488
let f_res = trans_callee(cx, f);
488489
ret trans_bind_1(cx, expr_ty(cx, f), f_res, args,
489-
ty::node_id_to_type(bcx_tcx(cx), id), dest);
490+
node_id_type(cx, id), dest);
490491
}
491492

492493
fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,

src/comp/middle/trans/common.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,16 @@ fn node_id_type(bcx: @block_ctxt, id: ast::node_id) -> ty::t {
910910
fn expr_ty(bcx: @block_ctxt, ex: @ast::expr) -> ty::t {
911911
node_id_type(bcx, ex.id)
912912
}
913+
fn node_id_type_params(bcx: @block_ctxt, id: ast::node_id) -> [ty::t] {
914+
let tcx = bcx_tcx(bcx);
915+
let params = ty::node_id_to_type_params(tcx, id);
916+
alt bcx.fcx.param_substs {
917+
some(substs) {
918+
vec::map(params) {|t| ty::substitute_type_params(tcx, substs.tys, t) }
919+
}
920+
_ { params }
921+
}
922+
}
913923

914924
//
915925
// Local Variables:

src/comp/middle/trans/impl.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,15 @@ fn trans_vtable_callee(bcx: @block_ctxt, self: ValueRef, dict: ValueRef,
116116
let bcx = bcx, ccx = bcx_ccx(bcx), tcx = ccx.tcx;
117117
let method = ty::iface_methods(tcx, iface_id)[n_method];
118118
let {ty: fty, llty: llfty} =
119-
wrapper_fn_ty(ccx, val_ty(dict), ty::node_id_to_type(tcx, callee_id),
119+
wrapper_fn_ty(ccx, val_ty(dict), node_id_type(bcx, callee_id),
120120
method.tps);
121121
let vtable = PointerCast(bcx, Load(bcx, GEPi(bcx, dict, [0, 0])),
122122
T_ptr(T_array(T_ptr(llfty), n_method + 1u)));
123123
let mptr = Load(bcx, GEPi(bcx, vtable, [0, n_method as int]));
124124
let generic = generic_none;
125125
if vec::len(*method.tps) > 0u || ty::type_has_params(fty) {
126126
let tydescs = [], tis = [];
127-
let tptys = ty::node_id_to_type_params(tcx, callee_id);
127+
let tptys = node_id_type_params(bcx, callee_id);
128128
for t in vec::tail_n(tptys, vec::len(tptys) - vec::len(*method.tps)) {
129129
let ti = none;
130130
let td = get_tydesc(bcx, t, true, ti).result;
@@ -246,7 +246,17 @@ fn resolve_dicts_in_fn_ctxt(fcx: @fn_ctxt, dicts: typeck::dict_res)
246246
result += [alt dict {
247247
typeck::dict_static(iid, tys, sub) {
248248
alt resolve_dicts_in_fn_ctxt(fcx, sub) {
249-
some(sub) { typeck::dict_static(iid, tys, sub) }
249+
some(sub) {
250+
let tys = alt fcx.param_substs {
251+
some(substs) {
252+
vec::map(tys, {|t|
253+
ty::substitute_type_params(fcx.ccx.tcx, substs.tys, t)
254+
})
255+
}
256+
_ { tys }
257+
};
258+
typeck::dict_static(iid, tys, sub)
259+
}
250260
none { ret none; }
251261
}
252262
}

src/comp/middle/ty.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,18 +1339,18 @@ fn field_idx(id: ast::ident, fields: [field]) -> option<uint> {
13391339
ret none;
13401340
}
13411341

1342-
fn get_field(tcx: ctxt, rec_ty: t, id: ast::ident) -> field {
1343-
alt vec::find(get_fields(tcx, rec_ty), {|f| str::eq(f.ident, id) }) {
1344-
some(f) { ret f; }
1345-
_ { tcx.sess.bug(#fmt("get_field: bad field id %s", id)); }
1342+
fn get_field(rec_ty: t, id: ast::ident) -> field {
1343+
alt vec::find(get_fields(rec_ty), {|f| str::eq(f.ident, id) }) {
1344+
some(f) { f }
1345+
_ { fail #fmt("get_field: bad field id %s", id); }
13461346
}
13471347
}
13481348

13491349
// TODO: could have a precondition instead of failing
1350-
fn get_fields(tcx:ctxt, rec_ty:t) -> [field] {
1350+
fn get_fields(rec_ty:t) -> [field] {
13511351
alt get(rec_ty).struct {
1352-
ty_rec(fields) { fields }
1353-
_ { tcx.sess.bug("get_fields called on non-record type"); }
1352+
ty_rec(fields) { fields }
1353+
_ { fail "get_fields called on non-record type"; }
13541354
}
13551355
}
13561356

0 commit comments

Comments
 (0)