Skip to content

Commit ace8058

Browse files
committed
rustc: Have typechecking no longer rebuild the AST
1 parent df9801c commit ace8058

File tree

3 files changed

+64
-49
lines changed

3 files changed

+64
-49
lines changed

src/comp/driver/rustc.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,9 @@ fn compile_input(session::session sess,
9999
auto ty_cx = ty::mk_ctxt(sess, def_map);
100100
auto typeck_result =
101101
time[typeck::typecheck_result](time_passes, "typechecking",
102-
bind typeck::check_crate(ty_cx, crate));
102+
bind typeck::check_crate(ty_cx, crate));
103103
auto node_type_table = typeck_result._0;
104104
auto type_cache = typeck_result._1;
105-
crate = typeck_result._2;
106105

107106
if (sess.get_opts().run_typestate) {
108107
crate = time(time_passes, "typestate checking",
@@ -130,7 +129,6 @@ fn pretty_print_input(session::session sess, eval::env env, str input,
130129
auto def_map = resolve::resolve_crate(sess, crate);
131130
auto ty_cx = ty::mk_ctxt(sess, def_map);
132131
auto typeck_result = typeck::check_crate(ty_cx, crate);
133-
crate = typeck_result._2;
134132
mode = pprust::mo_typed(ty_cx, typeck_result._0, typeck_result._1);
135133
} else {
136134
mode = pprust::mo_untyped;

src/comp/middle/typeck.rs

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,12 @@ type fn_purity_table = hashmap[ast::def_id, ast::purity];
6262
type unify_cache_entry = tup(ty::t,ty::t,vec[mutable ty::t]);
6363
type unify_cache = hashmap[unify_cache_entry,ty::unify::result];
6464

65+
type obj_info = rec(vec[ast::obj_field] obj_fields, ast::def_id this_obj);
66+
6567
type crate_ctxt = rec(session::session sess,
6668
ty::type_cache type_cache,
6769
@ty_item_table item_items,
68-
vec[ast::obj_field] obj_fields,
69-
option::t[ast::def_id] this_obj,
70+
mutable vec[obj_info] obj_infos,
7071
@fn_purity_table fn_purity_table,
7172
mutable int next_var_id,
7273
unify_cache unify_cache,
@@ -2275,21 +2276,10 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
22752276
auto t = ty::mk_nil(fcx.ccx.tcx);
22762277
let ty::t this_obj_ty;
22772278

2278-
auto this_obj_id = fcx.ccx.this_obj;
2279-
alt (this_obj_id) {
2280-
// If we're inside a current object, grab its type.
2281-
case (some[ast::def_id](?def_id)) {
2282-
this_obj_ty = ty::lookup_item_type(fcx.ccx.sess,
2283-
fcx.ccx.tcx, fcx.ccx.type_cache, def_id)._1;
2284-
}
2285-
// Otherwise, we should be able to look up the object we're
2286-
// "with".
2287-
case (_) {
2288-
// TODO.
2289-
2290-
fail;
2291-
}
2292-
}
2279+
auto oinfo_opt = get_obj_info(fcx.ccx);
2280+
auto this_obj_id = option::get[obj_info](oinfo_opt).this_obj;
2281+
this_obj_ty = ty::lookup_item_type(fcx.ccx.sess,
2282+
fcx.ccx.tcx, fcx.ccx.type_cache, this_obj_id)._1;
22932283

22942284
// Grab this method's type out of the current object type.
22952285
alt (struct(fcx.ccx.tcx, this_obj_ty)) {
@@ -2561,6 +2551,10 @@ fn next_ty_var(&@crate_ctxt ccx) -> ty::t {
25612551
ret t;
25622552
}
25632553

2554+
fn get_obj_info(&@crate_ctxt ccx) -> option::t[obj_info] {
2555+
ret vec::last[obj_info](ccx.obj_infos);
2556+
}
2557+
25642558
fn check_decl_local(&@fn_ctxt fcx, &@ast::decl decl) -> @ast::decl {
25652559
alt (decl.node) {
25662560
case (ast::decl_local(?local)) {
@@ -2661,8 +2655,7 @@ fn check_block(&@fn_ctxt fcx, &ast::block block) {
26612655
write_nil_type(fcx.ccx.tcx, fcx.ccx.node_types, block.node.a.id);
26622656
}
26632657

2664-
fn check_const(&@crate_ctxt ccx, &span sp, &ast::ident ident, &@ast::ty t,
2665-
&@ast::expr e, &ast::def_id id, &ast::ann ann) {
2658+
fn check_const(&@crate_ctxt ccx, &span sp, &@ast::expr e, &ast::ann ann) {
26662659
// FIXME: this is kinda a kludge; we manufacture a fake "function context"
26672660
// for checking the initializer expression.
26682661
auto rty = ann_to_type(ccx.node_types, ann);
@@ -2675,17 +2668,21 @@ fn check_const(&@crate_ctxt ccx, &span sp, &ast::ident ident, &@ast::ty t,
26752668
}
26762669

26772670
fn check_fn(&@crate_ctxt ccx, &ast::fn_decl decl, ast::proto proto,
2678-
&ast::block body) -> ast::_fn {
2671+
&ast::block body) {
26792672
auto local_ty_table = @common::new_def_hash[ty::t]();
26802673

26812674
// FIXME: duplicate work: the item annotation already has the arg types
26822675
// and return type translated to typeck::ty values. We don't need do to it
26832676
// again here, we can extract them.
26842677

2685-
2686-
for (ast::obj_field f in ccx.obj_fields) {
2687-
auto field_ty = ty::ann_to_type(ccx.node_types, f.ann);
2688-
local_ty_table.insert(f.id, field_ty);
2678+
alt (get_obj_info(ccx)) {
2679+
case (option::some[obj_info](?oinfo)) {
2680+
for (ast::obj_field f in oinfo.obj_fields) {
2681+
auto field_ty = ty::ann_to_type(ccx.node_types, f.ann);
2682+
local_ty_table.insert(f.id, field_ty);
2683+
}
2684+
}
2685+
case (option::none[obj_info]) { /* no fields */ }
26892686
}
26902687

26912688
// Store the type of each argument in the table.
@@ -2713,21 +2710,38 @@ fn check_fn(&@crate_ctxt ccx, &ast::fn_decl decl, ast::proto proto,
27132710
}
27142711

27152712
writeback::resolve_local_types_in_block(fcx, body);
2713+
}
27162714

2717-
ret rec(decl=decl, proto=proto, body=body);
2715+
fn check_method(&@crate_ctxt ccx, &@ast::method method) {
2716+
check_fn(ccx, method.node.meth.decl, method.node.meth.proto,
2717+
method.node.meth.body);
27182718
}
27192719

2720-
fn update_obj_fields(&@crate_ctxt ccx, &@ast::item i) -> @crate_ctxt {
2721-
alt (i.node) {
2720+
fn check_item(@crate_ctxt ccx, &@ast::item it) {
2721+
alt (it.node) {
2722+
case (ast::item_const(_, _, ?e, _, ?a)) {
2723+
check_const(ccx, it.span, e, a);
2724+
}
2725+
case (ast::item_fn(_, ?f, _, _, _)) {
2726+
check_fn(ccx, f.decl, f.proto, f.body);
2727+
}
27222728
case (ast::item_obj(_, ?ob, _, ?obj_def_ids, _)) {
2729+
// We're entering an object, so gather up the info we need.
27232730
let ast::def_id di = obj_def_ids.ty;
2724-
ret @rec(obj_fields = ob.fields,
2725-
this_obj = some[ast::def_id](di) with *ccx);
2726-
}
2727-
case (_) {
2731+
vec::push[obj_info](ccx.obj_infos,
2732+
rec(obj_fields=ob.fields, this_obj=di));
2733+
2734+
// Typecheck the methods.
2735+
for (@ast::method method in ob.methods) {
2736+
check_method(ccx, method);
2737+
}
2738+
option::may[@ast::method](bind check_method(ccx, _), ob.dtor);
2739+
2740+
// Now remove the info from the stack.
2741+
vec::pop[obj_info](ccx.obj_infos);
27282742
}
2743+
case (_) { /* nothing to do */ }
27292744
}
2730-
ret ccx;
27312745
}
27322746

27332747

@@ -2783,15 +2797,13 @@ fn mk_fn_purity_table(&@ast::crate crate) -> @fn_purity_table {
27832797
ret res;
27842798
}
27852799

2786-
// TODO: Remove the third element of this tuple; rely solely on the node type
2787-
// table.
2788-
type typecheck_result = tup(node_type_table, ty::type_cache, @ast::crate);
2800+
type typecheck_result = tup(node_type_table, ty::type_cache);
27892801

27902802
fn check_crate(&ty::ctxt tcx, &@ast::crate crate) -> typecheck_result {
27912803
auto sess = tcx.sess;
27922804
auto result = collect::collect_item_types(sess, tcx, crate);
27932805

2794-
let vec[ast::obj_field] fields = [];
2806+
let vec[obj_info] obj_infos = [];
27952807

27962808
auto hasher = hash_unify_cache_entry;
27972809
auto eqer = eq_unify_cache_entry;
@@ -2803,28 +2815,24 @@ fn check_crate(&ty::ctxt tcx, &@ast::crate crate) -> typecheck_result {
28032815
auto ccx = @rec(sess=sess,
28042816
type_cache=result._0,
28052817
item_items=result._1,
2806-
obj_fields=fields,
2807-
this_obj=none[ast::def_id],
2808-
fn_purity_table = fpt,
2818+
mutable obj_infos=obj_infos,
2819+
fn_purity_table=fpt,
28092820
mutable next_var_id=0,
28102821
unify_cache=unify_cache,
28112822
mutable cache_hits=0u,
28122823
mutable cache_misses=0u,
28132824
tcx=tcx,
28142825
node_types=node_types);
28152826

2816-
auto fld = fold::new_identity_fold[@crate_ctxt]();
2817-
2818-
fld = @rec(update_env_for_item = bind update_obj_fields(_, _),
2819-
fold_fn = bind check_fn(_,_,_,_)
2820-
with *fld);
2827+
auto visit = rec(visit_item_pre = bind check_item(ccx, _)
2828+
with walk::default_visitor());
28212829

2822-
auto crate_1 = fold::fold_crate[@crate_ctxt](ccx, fld, crate);
2830+
walk::walk_crate(visit, *crate);
28232831

28242832
log #fmt("cache hit rate: %u/%u", ccx.cache_hits,
28252833
ccx.cache_hits + ccx.cache_misses);
28262834

2827-
ret tup(node_types, ccx.type_cache, crate_1);
2835+
ret tup(node_types, ccx.type_cache);
28282836
}
28292837

28302838
//

src/lib/option.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ fn maybe[T, U](&U def, fn(&T) -> U f, &t[T] opt) -> U {
4949
case (some[T](?t)) { ret f(t); }
5050
}
5151
}
52+
53+
// Can be defined in terms of the above when/if we have const bind.
54+
fn may[T](fn(&T) f, &t[T] opt) {
55+
alt (opt) {
56+
case (none[T]) { /* nothing */ }
57+
case (some[T](?t)) { f(t); }
58+
}
59+
}
60+
5261
// Local Variables:
5362
// mode: rust;
5463
// fill-column: 78;

0 commit comments

Comments
 (0)