Skip to content

Commit a5bca7d

Browse files
committed
Refactor data structures representing constraints (again...)
I added a "resolved" version of the ast::constr type -- ty::constr_def -- that has a def_id field instead of an ann_field. This is more consistent with other types and eliminates some checking. Incidentally, I removed the def_map argument to the top-level function in middle::alias, since the ty::ctxt already has a def_map field.
1 parent 52d4f48 commit a5bca7d

File tree

14 files changed

+265
-233
lines changed

14 files changed

+265
-233
lines changed

src/comp/driver/rustc.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,18 @@ fn compile_input(session::session sess, eval::env env, str input,
8181
auto crate =
8282
time(time_passes, "parsing", bind parse_input(sess, p, input));
8383
if (sess.get_opts().output_type == link::output_type_none) { ret; }
84-
auto def_map =
84+
auto d =
8585
time(time_passes, "resolution",
8686
bind resolve::resolve_crate(sess, crate));
87-
auto ty_cx = ty::mk_ctxt(sess, def_map);
87+
auto ty_cx = ty::mk_ctxt(sess, d._0, d._1);
8888
time[()](time_passes, "typechecking",
8989
bind typeck::check_crate(ty_cx, crate));
9090
if (sess.get_opts().run_typestate) {
9191
time(time_passes, "typestate checking",
9292
bind middle::tstate::ck::check_crate(ty_cx, crate));
9393
}
9494
time(time_passes, "alias checking",
95-
bind middle::alias::check_crate(@ty_cx, def_map, crate));
95+
bind middle::alias::check_crate(@ty_cx, crate));
9696
auto llmod =
9797
time[llvm::llvm::ModuleRef](time_passes, "translation",
9898
bind trans::trans_crate(sess, crate,
@@ -109,8 +109,8 @@ fn pretty_print_input(session::session sess, eval::env env, str input,
109109
auto mode;
110110
alt (ppm) {
111111
case (ppm_typed) {
112-
auto def_map = resolve::resolve_crate(sess, crate);
113-
auto ty_cx = ty::mk_ctxt(sess, def_map);
112+
auto d = resolve::resolve_crate(sess, crate);
113+
auto ty_cx = ty::mk_ctxt(sess, d._0, d._1);
114114
typeck::check_crate(ty_cx, crate);
115115
mode = ppaux::mo_typed(ty_cx);
116116
}

src/comp/front/ast.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -359,19 +359,17 @@ tag constr_arg_general_[T] { carg_base; carg_ident(T); carg_lit(@lit); }
359359
360360
type constr_arg = constr_arg_general[uint];
361361
362-
type constr_arg_use = constr_arg_general[ident];
363-
364362
type constr_arg_general[T] = spanned[constr_arg_general_[T]];
365363
364+
type constr_ = rec(path path,
365+
vec[@constr_arg_general[uint]] args,
366+
ann ann);
366367
367-
// The ann field is there so that using the def_map in the type
368-
// context, we can get the def_id for the path.
369-
type constr_general[T] =
370-
rec(path path, vec[@constr_arg_general[T]] args, ann ann);
371-
372-
type constr = spanned[constr_general[uint]];
368+
type constr = spanned[constr_];
373369
374-
type constr_use = spanned[constr_general[ident]];
370+
/* The parser generates ast::constrs; resolve generates
371+
a mapping from each function to a list of ty::constr_defs,
372+
corresponding to these. */
375373
376374
type arg = rec(mode mode, @ty ty, ident ident, def_id id);
377375

src/comp/front/creader.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ fn parse_ty_or_bang(@pstate st, str_def sd) -> ty_or_bang {
7878
}
7979
}
8080

81-
fn parse_constrs(@pstate st, str_def sd) -> vec[@ast::constr] {
82-
let vec[@ast::constr] res = [];
81+
fn parse_constrs(@pstate st, str_def sd) -> vec[@ty::constr_def] {
82+
let vec[@ty::constr_def] res = [];
8383
alt (peek(st) as char) {
8484
case (':') {
8585
do {
@@ -92,7 +92,7 @@ fn parse_constrs(@pstate st, str_def sd) -> vec[@ast::constr] {
9292
ret res;
9393
}
9494

95-
fn parse_constr(@pstate st, str_def sd) -> @ast::constr {
95+
fn parse_constr(@pstate st, str_def sd) -> @ty::constr_def {
9696
st.tcx.sess.unimpl("Reading constraints " + " isn't implemented");
9797
/*
9898
let vec[@ast::constr_arg] args = [];
@@ -318,7 +318,7 @@ fn parse_hex(@pstate st) -> uint {
318318
}
319319

320320
fn parse_ty_fn(@pstate st, str_def sd) ->
321-
tup(vec[ty::arg], ty::t, ast::controlflow, vec[@ast::constr]) {
321+
tup(vec[ty::arg], ty::t, ast::controlflow, vec[@ty::constr_def]) {
322322
assert (next(st) as char == '[');
323323
let vec[ty::arg] inputs = [];
324324
while (peek(st) as char != ']') {

src/comp/middle/alias.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,11 @@ tag local_info { arg(ast::mode); objfield(ast::mutability); }
3535

3636
type ctx =
3737
rec(@ty::ctxt tcx,
38-
resolve::def_map dm,
3938
std::map::hashmap[def_num, local_info] local_map);
4039

41-
fn check_crate(@ty::ctxt tcx, resolve::def_map dm, &@ast::crate crate) {
40+
fn check_crate(@ty::ctxt tcx, &@ast::crate crate) {
4241
auto cx =
4342
@rec(tcx=tcx,
44-
dm=dm,
45-
4643
// Stores information about object fields and function
4744
// arguments that's otherwise not easily available.
4845
local_map=util::common::new_int_hash());
@@ -173,7 +170,7 @@ fn check_call(&ctx cx, &@ast::expr f, &vec[@ast::expr] args, &scope sc) ->
173170
if (vec::len(unsafe_ts) > 0u) {
174171
alt (f.node) {
175172
case (ast::expr_path(_, ?ann)) {
176-
if (def_is_local(cx.dm.get(ann.id), true)) {
173+
if (def_is_local(cx.tcx.def_map.get(ann.id), true)) {
177174
cx.tcx.sess.span_err
178175
(f.span, #fmt("function may alias with argument \
179176
%u, which is not immutably rooted",
@@ -231,7 +228,7 @@ fn check_tail_call(&ctx cx, &@ast::expr call) {
231228
auto ok = true;
232229
alt (args.(i).node) {
233230
case (ast::expr_path(_, ?ann)) {
234-
auto def = cx.dm.get(ann.id);
231+
auto def = cx.tcx.def_map.get(ann.id);
235232
auto dnum = ast::def_id_of_def(def)._1;
236233
alt (cx.local_map.find(dnum)) {
237234
case (some(arg(ast::alias(?mut)))) {
@@ -353,7 +350,7 @@ fn check_for(&ctx cx, &@ast::local local, &@ast::expr seq, &ast::block block,
353350

354351
fn check_var(&ctx cx, &@ast::expr ex, &ast::path p, ast::ann ann, bool assign,
355352
&scope sc) {
356-
auto def = cx.dm.get(ann.id);
353+
auto def = cx.tcx.def_map.get(ann.id);
357354
if (!def_is_local(def, true)) { ret; }
358355
auto my_defnum = ast::def_id_of_def(def)._1;
359356
auto var_t = ty::expr_ty(*cx.tcx, ex);
@@ -379,7 +376,7 @@ fn check_assign(&@ctx cx, &@ast::expr dest, &@ast::expr src, &scope sc,
379376
visit_expr(cx, src, sc, v);
380377
alt (dest.node) {
381378
case (ast::expr_path(?p, ?ann)) {
382-
auto dnum = ast::def_id_of_def(cx.dm.get(ann.id))._1;
379+
auto dnum = ast::def_id_of_def(cx.tcx.def_map.get(ann.id))._1;
383380
if (is_immutable_alias(cx, sc, dnum)) {
384381
cx.tcx.sess.span_err(dest.span,
385382
"assigning to immutable alias");
@@ -566,7 +563,7 @@ fn inner_mut(&vec[deref] ds) -> option::t[ty::t] {
566563
fn path_def_id(&ctx cx, &@ast::expr ex) -> option::t[ast::def_id] {
567564
alt (ex.node) {
568565
case (ast::expr_path(_, ?ann)) {
569-
ret some(ast::def_id_of_def(cx.dm.get(ann.id)));
566+
ret some(ast::def_id_of_def(cx.tcx.def_map.get(ann.id)));
570567
}
571568
case (_) { ret none; }
572569
}

src/comp/middle/metadata.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,7 @@ mod Encode {
221221
case (ast::native_abi_cdecl) { w.write_char('c'); }
222222
case (ast::native_abi_llvm) { w.write_char('l'); }
223223
}
224-
let vec[@constr] res_constrs = [];
225-
enc_ty_fn(w, cx, args, out, ast::return, res_constrs);
224+
enc_ty_fn(w, cx, args, out, ast::return, []);
226225
}
227226
case (ty::ty_obj(?methods)) {
228227
w.write_str("O[");
@@ -253,7 +252,7 @@ mod Encode {
253252
}
254253
}
255254
fn enc_ty_fn(&io::writer w, &@ctxt cx, &vec[ty::arg] args, &ty::t out,
256-
&ast::controlflow cf, &vec[@ast::constr] constrs) {
255+
&ast::controlflow cf, &vec[@ty::constr_def] constrs) {
257256
w.write_char('[');
258257
for (ty::arg arg in args) {
259258
alt (arg.mode) {
@@ -271,15 +270,15 @@ mod Encode {
271270
case (_) { enc_ty(w, cx, out); }
272271
}
273272
auto colon = true;
274-
for (@ast::constr c in constrs) {
273+
for (@ty::constr_def c in constrs) {
275274
if (colon) {
276275
w.write_char(':');
277276
colon = false;
278277
} else { w.write_char(','); }
279278
enc_constr(w, cx, c);
280279
}
281280
}
282-
fn enc_constr(&io::writer w, &@ctxt cx, &@ast::constr c) {
281+
fn enc_constr(&io::writer w, &@ctxt cx, &@ty::constr_def c) {
283282
w.write_str(path_to_str(c.node.path));
284283
w.write_char('(');
285284
// FIXME

src/comp/middle/resolve.rs

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import util::common::new_int_hash;
1111
import util::common::new_uint_hash;
1212
import util::common::new_str_hash;
1313
import util::common::span;
14-
import middle::tstate::ann::ts_ann;
14+
import util::common::respan;
15+
import middle::ty::constr_table;
1516
import visit::vt;
1617
import std::map::hashmap;
1718
import std::list;
@@ -111,24 +112,26 @@ type def_map = hashmap[uint, def];
111112
type env =
112113
rec(crate_map crate_map,
113114
def_map def_map,
115+
constr_table fn_constrs,
114116
hashmap[def_id, @ast::item] ast_map,
115117
hashmap[ast::def_num, import_state] imports,
116118
hashmap[ast::def_num, @indexed_mod] mod_map,
117119
hashmap[def_id, vec[ident]] ext_map,
118120
ext_hash ext_cache,
119121
session sess);
120122

121-
122123
// Used to distinguish between lookups from outside and from inside modules,
123124
// since export restrictions should only be applied for the former.
124125
tag dir { inside; outside; }
125126

126127
tag namespace { ns_value; ns_type; ns_module; }
127128

128-
fn resolve_crate(session sess, @ast::crate crate) -> def_map {
129+
fn resolve_crate(session sess, @ast::crate crate)
130+
-> tup(def_map, constr_table) {
129131
auto e =
130132
@rec(crate_map=new_uint_hash[ast::crate_num](),
131133
def_map=new_uint_hash[def](),
134+
fn_constrs = new_def_hash[vec[ty::constr_def]](),
132135
ast_map=new_def_hash[@ast::item](),
133136
imports=new_int_hash[import_state](),
134137
mod_map=new_int_hash[@indexed_mod](),
@@ -140,7 +143,7 @@ fn resolve_crate(session sess, @ast::crate crate) -> def_map {
140143
resolve_imports(*e);
141144
check_for_collisions(e, *crate);
142145
resolve_names(e, crate);
143-
ret e.def_map;
146+
ret tup(e.def_map, e.fn_constrs);
144147
}
145148

146149

@@ -266,8 +269,9 @@ fn resolve_names(&@env e, &@ast::crate c) {
266269
visit_arm=bind walk_arm(e, _, _, _),
267270
visit_expr=bind walk_expr(e, _, _, _),
268271
visit_ty=bind walk_ty(e, _, _, _),
269-
visit_fn=visit_fn_with_scope,
270-
visit_constr=bind walk_constr(e, _, _, _)
272+
visit_constr = bind walk_constr(e, _, _, _),
273+
visit_fn=bind visit_fn_with_scope
274+
(e, _, _, _, _, _, _, _, _)
271275
with *visit::default_visitor());
272276
visit::visit_crate(*c, cons(scope_crate(c), @nil), visit::vtor(v));
273277
fn walk_expr(@env e, &@ast::expr exp, &scopes sc, &vt[scopes] v) {
@@ -282,12 +286,7 @@ fn resolve_names(&@env e, &@ast::crate c) {
282286
case (_) { }
283287
}
284288
}
285-
fn walk_constr(@env e, &@ast::constr c, &scopes sc, &vt[scopes] v) {
286-
auto new_def =
287-
lookup_path_strict(*e, sc, c.span, c.node.path.node.idents,
288-
ns_value);
289-
e.def_map.insert(c.node.ann.id, new_def);
290-
}
289+
291290
fn walk_ty(@env e, &@ast::ty t, &scopes sc, &vt[scopes] v) {
292291
visit::visit_ty(t, sc, v);
293292
alt (t.node) {
@@ -300,6 +299,13 @@ fn resolve_names(&@env e, &@ast::crate c) {
300299
case (_) { }
301300
}
302301
}
302+
303+
fn walk_constr(@env e, &@ast::constr c, &scopes sc, &vt[scopes] v) {
304+
auto new_def = lookup_path_strict(*e, sc, c.span,
305+
c.node.path.node.idents, ns_value);
306+
e.def_map.insert(c.node.ann.id, new_def);
307+
}
308+
303309
fn walk_arm(@env e, &ast::arm a, &scopes sc, &vt[scopes] v) {
304310
walk_pat(*e, sc, a.pat);
305311
visit_arm_with_scope(a, sc, v);
@@ -338,11 +344,16 @@ fn visit_native_item_with_scope(&@ast::native_item ni, &scopes sc,
338344
visit::visit_native_item(ni, cons(scope_native_item(ni), @sc), v);
339345
}
340346

341-
fn visit_fn_with_scope(&ast::_fn f, &vec[ast::ty_param] tp, &span sp,
347+
fn visit_fn_with_scope(&@env e, &ast::_fn f, &vec[ast::ty_param] tp, &span sp,
342348
&ident name, &def_id d_id, &ann a, &scopes sc,
343349
&vt[scopes] v) {
344-
visit::visit_fn(f, tp, sp, name, d_id, a, cons(scope_fn(f.decl, tp), @sc),
345-
v);
350+
// here's where we need to set up the mapping
351+
// for f's constrs in the table.
352+
for (@ast::constr c in f.decl.constraints) {
353+
resolve_constr(e, d_id, c, sc, v);
354+
}
355+
visit::visit_fn(f, tp, sp, name, d_id, a,
356+
cons(scope_fn(f.decl, tp), @sc), v);
346357
}
347358

348359
fn visit_block_with_scope(&ast::block b, &scopes sc, &vt[scopes] v) {
@@ -389,6 +400,37 @@ fn follow_import(&env e, &scopes sc, vec[ident] path, &span sp) -> def {
389400
}
390401
}
391402

403+
fn resolve_constr(@env e, &def_id d_id, &@ast::constr c, &scopes sc,
404+
&vt[scopes] v) {
405+
let def new_def = lookup_path_strict(*e, sc, c.span,
406+
c.node.path.node.idents,
407+
ns_value);
408+
alt (new_def) {
409+
case (ast::def_fn(?pred_id)) {
410+
let ty::constr_general[uint] c_ = rec(path=c.node.path,
411+
args=c.node.args,
412+
id=pred_id);
413+
let ty::constr_def new_constr = respan(c.span, c_);
414+
add_constr(e, d_id, new_constr);
415+
}
416+
case (_) {
417+
e.sess.span_err(c.span, "Non-predicate in constraint: "
418+
+ ty::path_to_str(c.node.path));
419+
}
420+
}
421+
}
422+
423+
fn add_constr(&@env e, &def_id d_id, &ty::constr_def c) {
424+
e.fn_constrs.insert(d_id,
425+
alt (e.fn_constrs.find(d_id)) {
426+
case (none) {
427+
[c]
428+
}
429+
case (some(?cs)) {
430+
cs + [c]
431+
}
432+
});
433+
}
392434

393435
// Import resolution
394436
fn resolve_import(&env e, &@ast::view_item it, &scopes sc) {

src/comp/middle/tstate/auxiliary.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,9 @@ to represent predicate *arguments* however. This type
198198
Both types store an ident and span, for error-logging purposes.
199199
*/
200200
type pred_desc_ = rec(vec[@constr_arg_use] args, uint bit_num);
201-
202201
type pred_desc = spanned[pred_desc_];
202+
type constr_arg_use = constr_arg_general[ident];
203+
203204

204205
tag constraint {
205206
cinit(uint, span, ident);
@@ -456,7 +457,7 @@ fn controlflow_expr(&crate_ctxt ccx, @expr e) -> controlflow {
456457
}
457458
}
458459

459-
fn constraints_expr(&ty::ctxt cx, @expr e) -> vec[@ast::constr] {
460+
fn constraints_expr(&ty::ctxt cx, @expr e) -> vec[@ty::constr_def] {
460461
alt (ty::struct(cx, ty::ann_to_type(cx, expr_ann(e)))) {
461462
case (ty::ty_fn(_, _, _, _, ?cs)) { ret cs; }
462463
case (_) { ret []; }
@@ -511,9 +512,11 @@ fn constraints(&fn_ctxt fcx) -> vec[norm_constraint] {
511512
// FIXME:
512513
// this probably doesn't handle name shadowing well (or at all)
513514
// variables should really always be id'd by def_id and not ident
515+
514516
fn match_args(&fn_ctxt fcx, vec[pred_desc] occs, vec[@constr_arg_use] occ) ->
515517
uint {
516-
log "match_args: looking at " + pretty::ppaux::constr_args_to_str_1(occ);
518+
log ("match_args: looking at " +
519+
pretty::ppaux::constr_args_to_str(std::util::id[str], occ));
517520
for (pred_desc pd in occs) {
518521
log "match_args: candidate " + pred_desc_to_str(pd);
519522
if (ty::args_eq(str::eq, pd.node.args, occ)) { ret pd.node.bit_num; }
@@ -586,11 +589,13 @@ fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr {
586589

587590
fn pred_desc_to_str(&pred_desc p) -> str {
588591
ret "<" + uistr(p.node.bit_num) + ", " +
589-
pretty::ppaux::constr_args_to_str_1(p.node.args) + ">";
592+
pretty::ppaux::constr_args_to_str(std::util::id[str], p.node.args)
593+
+ ">";
590594
}
591595

592-
fn substitute_constr_args(&ty::ctxt cx, &vec[@expr] actuals, &@ast::constr c)
593-
-> constr__ {
596+
fn substitute_constr_args(&ty::ctxt cx,
597+
&vec[@expr] actuals, &@ty::constr_def c)
598+
-> constr__ {
594599
let vec[@constr_arg_use] res = [];
595600
for (@constr_arg a in c.node.args) {
596601
res += [substitute_arg(cx, actuals, a)];

0 commit comments

Comments
 (0)