Skip to content

Commit 1dd2f1e

Browse files
committed
Get very simple impl method calls to compile
Resolution is still dumb, and no self support yet.
1 parent 6a16f57 commit 1dd2f1e

File tree

6 files changed

+103
-60
lines changed

6 files changed

+103
-60
lines changed

src/comp/driver/rustc.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
171171
time(time_passes, "const checking",
172172
bind middle::check_const::check_crate(sess, crate));
173173
let ty_cx = ty::mk_ctxt(sess, def_map, ext_map, ast_map, freevars);
174-
time(time_passes, "typechecking",
175-
bind typeck::check_crate(ty_cx, impl_map, crate));
174+
let method_map = time(time_passes, "typechecking",
175+
bind typeck::check_crate(ty_cx, impl_map, crate));
176176
time(time_passes, "block-use checking",
177177
bind middle::block_use::check_crate(ty_cx, crate));
178178
time(time_passes, "function usage",
@@ -190,7 +190,7 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
190190
let last_uses = time(time_passes, "last use finding",
191191
bind last_use::find_last_uses(crate, def_map, ref_map, ty_cx));
192192
time(time_passes, "kind checking",
193-
bind kind::check_crate(ty_cx, last_uses, crate));
193+
bind kind::check_crate(ty_cx, method_map, last_uses, crate));
194194
if sess.get_opts().no_trans { ret; }
195195

196196
let outputs = build_output_filenames(input, outdir, output, sess);
@@ -199,7 +199,8 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
199199
time(time_passes, "translation",
200200
bind trans::trans_crate(sess, crate, ty_cx,
201201
outputs.obj_filename, exp_map, ast_map,
202-
mut_map, copy_map, last_uses));
202+
mut_map, copy_map, last_uses,
203+
method_map));
203204
time(time_passes, "LLVM passes",
204205
bind link::write::run_passes(sess, llmod, outputs.obj_filename));
205206

src/comp/middle/kind.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ type rval_map = std::map::hashmap<node_id, ()>;
3030

3131
type ctx = {tcx: ty::ctxt,
3232
rval_map: rval_map,
33+
method_map: typeck::method_map,
3334
last_uses: last_use::last_uses};
3435

35-
fn check_crate(tcx: ty::ctxt, last_uses: last_use::last_uses,
36-
crate: @crate) -> rval_map {
36+
fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map,
37+
last_uses: last_use::last_uses, crate: @crate)
38+
-> rval_map {
3739
let ctx = {tcx: tcx,
3840
rval_map: std::map::new_int_hash(),
41+
method_map: method_map,
3942
last_uses: last_uses};
4043
let visit = visit::mk_vt(@{
4144
visit_expr: check_expr,
@@ -150,7 +153,8 @@ fn maybe_copy(cx: ctx, ex: @expr) {
150153
}
151154

152155
fn check_copy_ex(cx: ctx, ex: @expr, _warn: bool) {
153-
if ty::expr_is_lval(cx.tcx, ex) && !cx.last_uses.contains_key(ex.id) {
156+
if ty::expr_is_lval(cx.method_map, cx.tcx, ex) &&
157+
!cx.last_uses.contains_key(ex.id) {
154158
let ty = ty::expr_ty(cx.tcx, ex);
155159
check_copy(cx, ty, ex.span);
156160
// FIXME turn this on again once vector types are no longer unique.

src/comp/middle/trans.rs

Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// but many TypeRefs correspond to one ty::t; for instance, tup(int, int,
1414
// int) and rec(x=int, y=int, z=int) will have the same TypeRef.
1515

16-
import core::{either, str, uint, option, vec};
16+
import core::{either, str, int, uint, option, vec};
1717
import std::{map, time};
1818
import std::map::hashmap;
1919
import std::map::{new_int_hash, new_str_hash};
@@ -948,8 +948,6 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool,
948948
&static_ti: option::t<@tydesc_info>) -> result {
949949
alt cx.fcx.derived_tydescs.find(t) {
950950
some(info) {
951-
952-
953951
// If the tydesc escapes in this context, the cached derived
954952
// tydesc also has to be one that was marked as escaping.
955953
if !(escapes && !info.escapes) && storage == tps_normal {
@@ -2606,8 +2604,9 @@ fn trans_external_path(cx: @block_ctxt, did: ast::def_id,
26062604
type_of_ty_param_kinds_and_ty(lcx, cx.sp, tpt));
26072605
}
26082606

2609-
fn lval_static_fn(bcx: @block_ctxt, tpt: ty::ty_param_kinds_and_ty,
2610-
fn_id: ast::def_id, id: ast::node_id) -> lval_maybe_callee {
2607+
fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
2608+
-> lval_maybe_callee {
2609+
let tpt = ty::lookup_item_type(bcx_tcx(bcx), fn_id);
26112610
let val = if fn_id.crate == ast::local_crate {
26122611
// Internal reference.
26132612
assert (bcx_ccx(bcx).item_ids.contains_key(fn_id.node));
@@ -2698,17 +2697,13 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
26982697
let ccx = bcx_ccx(cx);
26992698
alt def {
27002699
ast::def_fn(did, _) | ast::def_native_fn(did, _) {
2701-
let tyt = ty::lookup_item_type(ccx.tcx, did);
2702-
ret lval_static_fn(cx, tyt, did, id);
2700+
ret lval_static_fn(cx, did, id);
27032701
}
27042702
ast::def_variant(tid, vid) {
2705-
let v_tyt = ty::lookup_item_type(ccx.tcx, vid);
2706-
alt ty::struct(ccx.tcx, v_tyt.ty) {
2707-
ty::ty_fn(_, _, _, _, _) {
2703+
if vec::len(ty::tag_variant_with_id(ccx.tcx, tid, vid).args) > 0u {
27082704
// N-ary variant.
2709-
ret lval_static_fn(cx, v_tyt, vid, id);
2710-
}
2711-
_ {
2705+
ret lval_static_fn(cx, vid, id);
2706+
} else {
27122707
// Nullary variant.
27132708
let tag_ty = node_id_type(ccx, id);
27142709
let alloc_result = alloc_ty(cx, tag_ty);
@@ -2724,7 +2719,6 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
27242719
} else { C_int(ccx, 0) };
27252720
Store(bcx, d, lldiscrimptr);
27262721
ret lval_no_env(bcx, lltagptr, temporary);
2727-
}
27282722
}
27292723
}
27302724
ast::def_const(did) {
@@ -2838,15 +2832,30 @@ fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
28382832
ret lval_owned(next_cx, elt);
28392833
}
28402834

2835+
// This is for impl methods, not obj methods.
2836+
fn trans_method_callee(bcx: @block_ctxt, e: @ast::expr, base: @ast::expr,
2837+
did: ast::def_id) -> lval_maybe_callee {
2838+
let bcx = trans_expr(bcx, base, ignore); // FIXME pass self
2839+
lval_static_fn(bcx, did, e.id)
2840+
}
2841+
28412842
fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
28422843
alt e.node {
28432844
ast::expr_path(p) { ret trans_path(bcx, p, e.id); }
28442845
ast::expr_field(base, ident) {
2846+
let method_map = bcx_ccx(bcx).method_map;
28452847
// Lval means this is a record field, so not a method
2846-
if !ty::expr_is_lval(bcx_tcx(bcx), e) {
2847-
let of = trans_object_field(bcx, base, ident);
2848-
ret {bcx: of.bcx, val: of.mthptr, kind: owned,
2849-
env: obj_env(of.objptr), generic: none};
2848+
if !ty::expr_is_lval(method_map, bcx_tcx(bcx), e) {
2849+
alt method_map.find(e.id) {
2850+
some(did) { // An impl method
2851+
ret trans_method_callee(bcx, e, base, did);
2852+
}
2853+
none. { // An object method
2854+
let of = trans_object_field(bcx, base, ident);
2855+
ret {bcx: of.bcx, val: of.mthptr, kind: owned,
2856+
env: obj_env(of.objptr), generic: none};
2857+
}
2858+
}
28502859
}
28512860
}
28522861
ast::expr_self_method(ident) {
@@ -3466,7 +3475,7 @@ fn trans_expr_save_in(bcx: @block_ctxt, e: @ast::expr, dest: ValueRef)
34663475
// use trans_temp_expr.
34673476
fn trans_temp_lval(bcx: @block_ctxt, e: @ast::expr) -> lval_result {
34683477
let bcx = bcx;
3469-
if ty::expr_is_lval(bcx_tcx(bcx), e) {
3478+
if ty::expr_is_lval(bcx_ccx(bcx).method_map, bcx_tcx(bcx), e) {
34703479
ret trans_lval(bcx, e);
34713480
} else {
34723481
let tcx = bcx_tcx(bcx);
@@ -3504,7 +3513,9 @@ fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> result {
35043513
// - exprs with non-immediate type never get dest=by_val
35053514
fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
35063515
let tcx = bcx_tcx(bcx);
3507-
if ty::expr_is_lval(tcx, e) { ret lval_to_dps(bcx, e, dest); }
3516+
if ty::expr_is_lval(bcx_ccx(bcx).method_map, tcx, e) {
3517+
ret lval_to_dps(bcx, e, dest);
3518+
}
35083519

35093520
alt e.node {
35103521
ast::expr_if(cond, thn, els) | ast::expr_if_check(cond, thn, els) {
@@ -3544,7 +3555,9 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
35443555
ret trans_closure::trans_bind(bcx, f, args, e.id, dest);
35453556
}
35463557
ast::expr_copy(a) {
3547-
if !ty::expr_is_lval(tcx, a) { ret trans_expr(bcx, a, dest); }
3558+
if !ty::expr_is_lval(bcx_ccx(bcx).method_map, tcx, a) {
3559+
ret trans_expr(bcx, a, dest);
3560+
}
35483561
else { ret lval_to_dps(bcx, a, dest); }
35493562
}
35503563
ast::expr_cast(val, _) {
@@ -3945,7 +3958,8 @@ fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt {
39453958
alt local.node.init {
39463959
some(init) {
39473960
if init.op == ast::init_assign ||
3948-
!ty::expr_is_lval(bcx_tcx(bcx), init.expr) {
3961+
!ty::expr_is_lval(bcx_ccx(bcx).method_map, bcx_tcx(bcx),
3962+
init.expr) {
39493963
bcx = trans_expr_save_in(bcx, init.expr, llptr);
39503964
} else { // This is a move from an lval, must perform an actual move
39513965
let sub = trans_lval(bcx, init.expr);
@@ -4641,6 +4655,18 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
46414655
finish_fn(fcx, lltop);
46424656
}
46434657

4658+
fn trans_impl(cx: @local_ctxt, name: ast::ident, methods: [@ast::method]) {
4659+
let sub_cx = extend_path(cx, name);
4660+
for m in methods {
4661+
alt cx.ccx.item_ids.find(m.node.id) {
4662+
some(llfndecl) {
4663+
trans_fn(extend_path(sub_cx, m.node.ident), m.span, m.node.meth,
4664+
llfndecl, none, [], m.node.id);
4665+
}
4666+
}
4667+
}
4668+
}
4669+
46444670

46454671
// FIXME: this should do some structural hash-consing to avoid
46464672
// duplicate constants. I think. Maybe LLVM has a magical mode
@@ -4949,10 +4975,7 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
49494975
with *extend_path(cx, item.ident)};
49504976
trans_obj(sub_cx, item.span, ob, ctor_id, tps);
49514977
}
4952-
ast::item_impl(_, _, _) {
4953-
4954-
fail "FIXME[impl]";
4955-
}
4978+
ast::item_impl(_, _, ms) { trans_impl(cx, item.ident, ms); }
49564979
ast::item_res(dtor, dtor_id, tps, ctor_id) {
49574980
trans_res_ctor(cx, item.span, dtor, ctor_id, tps);
49584981

@@ -5167,8 +5190,6 @@ fn raw_native_fn_type(ccx: @crate_ctxt, sp: span, args: [ty::arg],
51675190
ret T_fn(type_of_explicit_args(ccx, sp, args), type_of(ccx, sp, ret_ty));
51685191
}
51695192

5170-
fn item_path(item: @ast::item) -> [str] { ret [item.ident]; }
5171-
51725193
fn link_name(i: @ast::native_item) -> str {
51735194
alt attr::get_meta_item_value_str_by_name(i.attrs, "link_name") {
51745195
none. { ret i.ident; }
@@ -5259,12 +5280,12 @@ fn collect_item_1(ccx: @crate_ctxt, abi: @mutable option::t<ast::native_abi>,
52595280
}
52605281
_ { }
52615282
}
5262-
visit::visit_item(i, pt + item_path(i), v);
5283+
visit::visit_item(i, pt + [i.ident], v);
52635284
}
52645285

52655286
fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
52665287
v: vt<[str]>) {
5267-
let new_pt = pt + item_path(i);
5288+
let new_pt = pt + [i.ident];
52685289
visit::visit_item(i, new_pt, v);
52695290
alt i.node {
52705291
ast::item_fn(f, tps) {
@@ -5278,6 +5299,13 @@ fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
52785299
ccx.obj_methods.insert(m.node.id, ());
52795300
}
52805301
}
5302+
ast::item_impl(_, _, methods) {
5303+
let name = ccx.names.next(i.ident);
5304+
for m in methods {
5305+
register_fn(ccx, i.span, pt + [name, m.node.ident],
5306+
"impl_method", [], m.node.id);
5307+
}
5308+
}
52815309
ast::item_res(_, dtor_id, tps, ctor_id) {
52825310
register_fn(ccx, i.span, new_pt, "res_ctor", tps, ctor_id);
52835311
// Note that the destructor is associated with the item's id, not
@@ -5307,7 +5335,7 @@ fn collect_items(ccx: @crate_ctxt, crate: @ast::crate) {
53075335

53085336
fn collect_tag_ctor(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
53095337
v: vt<[str]>) {
5310-
let new_pt = pt + item_path(i);
5338+
let new_pt = pt + [i.ident];
53115339
visit::visit_item(i, new_pt, v);
53125340
alt i.node {
53135341
ast::item_tag(variants, tps) {
@@ -5333,7 +5361,7 @@ fn collect_tag_ctors(ccx: @crate_ctxt, crate: @ast::crate) {
53335361
// The constant translation pass.
53345362
fn trans_constant(ccx: @crate_ctxt, it: @ast::item, &&pt: [str],
53355363
v: vt<[str]>) {
5336-
let new_pt = pt + item_path(it);
5364+
let new_pt = pt + [it.ident];
53375365
visit::visit_item(it, new_pt, v);
53385366
alt it.node {
53395367
ast::item_tag(variants, _) {
@@ -5520,7 +5548,7 @@ fn write_abi_version(ccx: @crate_ctxt) {
55205548
fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
55215549
output: str, emap: resolve::exp_map, amap: ast_map::map,
55225550
mut_map: mut::mut_map, copy_map: alias::copy_map,
5523-
last_uses: last_use::last_uses)
5551+
last_uses: last_use::last_uses, method_map: typeck::method_map)
55245552
-> (ModuleRef, link::link_meta) {
55255553
let sha = std::sha1::mk_sha1();
55265554
let link_meta = link::build_link_meta(sess, *crate, output, sha);
@@ -5595,6 +5623,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
55955623
mut_map: mut_map,
55965624
copy_map: copy_map,
55975625
last_uses: last_uses,
5626+
method_map: method_map,
55985627
stats:
55995628
{mutable n_static_tydescs: 0u,
56005629
mutable n_derived_tydescs: 0u,

src/comp/middle/trans_common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ type crate_ctxt =
104104
mut_map: mut::mut_map,
105105
copy_map: alias::copy_map,
106106
last_uses: last_use::last_uses,
107+
method_map: typeck::method_map,
107108
stats: stats,
108109
upcalls: @upcall::upcalls,
109110
rust_object_type: TypeRef,

src/comp/middle/ty.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,15 +1672,18 @@ fn expr_has_ty_params(cx: ctxt, expr: @ast::expr) -> bool {
16721672
ret node_id_has_type_params(cx, expr.id);
16731673
}
16741674

1675-
fn expr_is_lval(tcx: ty::ctxt, e: @ast::expr) -> bool {
1675+
fn expr_is_lval(method_map: typeck::method_map, tcx: ty::ctxt,
1676+
e: @ast::expr) -> bool {
16761677
alt e.node {
16771678
ast::expr_path(_) | ast::expr_index(_, _) |
16781679
ast::expr_unary(ast::deref., _) { true }
16791680
ast::expr_field(base, ident) {
1680-
let basety = type_autoderef(tcx, expr_ty(tcx, base));
1681-
alt struct(tcx, basety) {
1682-
ty_obj(_) { false }
1683-
ty_rec(_) { true }
1681+
method_map.contains_key(e.id) ? false : {
1682+
let basety = type_autoderef(tcx, expr_ty(tcx, base));
1683+
alt struct(tcx, basety) {
1684+
ty_obj(_) { false }
1685+
ty_rec(_) { true }
1686+
}
16841687
}
16851688
}
16861689
_ { false }

0 commit comments

Comments
 (0)