Enable kind checking on typarams, fix kind constraints in library and comp.

This commit is contained in:
Graydon Hoare 2011-07-29 18:38:22 -07:00
parent 6ba4e34959
commit 0c9b749d20
11 changed files with 85 additions and 62 deletions

View file

@ -47,7 +47,7 @@ fn map_expr(map: &map, ex: &@expr, e: &(), v: &vt[()]) {
visit::visit_expr(ex, e, v);
}
fn new_smallintmap_int_adapter[V]() -> std::map::hashmap[int, V] {
fn new_smallintmap_int_adapter[@V]() -> std::map::hashmap[int, V] {
let key_idx = fn (key: &int) -> uint { key as uint };
let idx_key = fn (idx: &uint) -> int { idx as int };
ret new_smallintmap_adapter(key_idx, idx_key);
@ -58,15 +58,15 @@ fn new_smallintmap_int_adapter[V]() -> std::map::hashmap[int, V] {
// the entire codebase adapting all the callsites to the different
// interface.
// FIXME: hashmap and smallintmap should support the same interface.
fn new_smallintmap_adapter[K,
V](key_idx: fn(&K) -> uint ,
idx_key: fn(&uint) -> K ) ->
fn new_smallintmap_adapter[@K,
@V](key_idx: fn(&K) -> uint ,
idx_key: fn(&uint) -> K ) ->
std::map::hashmap[K, V] {
obj adapter[K,
V](map: smallintmap::smallintmap[V],
key_idx: fn(&K) -> uint ,
idx_key: fn(&uint) -> K ) {
obj adapter[@K,
@V](map: smallintmap::smallintmap[V],
key_idx: fn(&K) -> uint ,
idx_key: fn(&uint) -> K ) {
fn size() -> uint { fail }

View file

@ -74,6 +74,8 @@
import syntax::ast;
import syntax::visit;
import std::ivec;
import ast::kind;
import ast::kind_unique;
import ast::kind_shared;
@ -138,10 +140,31 @@ fn check_expr(tcx: &ty::ctxt, e: &@ast::expr) {
ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); }
ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, "="); }
ast::expr_swap(a, b) { need_shared_lhs_rhs(tcx, a, b, "<->"); }
ast::expr_call(callee, args) {
// FIXME: when ready, start checking param kinds against args.
// This will break stdlib again.
// let tpt = ty::expr_ty_params_and_ty(tcx, callee);
ast::expr_call(callee, _) {
let tpt = ty::expr_ty_params_and_ty(tcx, callee);
// If we have typarams, we're calling an item; we need to check
// that all the types we're supplying as typarams conform to the
// typaram kind constraints on that item.
if ivec::len(tpt.params) != 0u {
let callee_def = ast::def_id_of_def(tcx.def_map.get(callee.id));
let item_tk = ty::lookup_item_type(tcx, callee_def);
let i = 0;
assert ivec::len(item_tk.kinds) == ivec::len(tpt.params);
for k_need: ast::kind in item_tk.kinds {
let t = tpt.params.(i);
let k = ty::type_kind(tcx, t);
if ! kind_lteq(k_need, k) {
let s = #fmt("mismatched kinds for typaram %d: \
needed %s type, got %s type %s",
i,
kind_to_str(k_need),
kind_to_str(k),
util::ppaux::ty_to_str(tcx, t));
tcx.sess.span_err(e.span, s);
}
i += 1;
}
}
}
_ { }
}

View file

@ -16,11 +16,11 @@ type interner[T] =
hasher: hashfn[T],
eqer: eqfn[T]};
fn mk[T](hasher: hashfn[T], eqer: eqfn[T]) -> interner[T] {
fn mk[@T](hasher: hashfn[T], eqer: eqfn[T]) -> interner[T] {
let m = map::mk_hashmap[T, uint](hasher, eqer);
ret {map: m, mutable vect: ~[], hasher: hasher, eqer: eqer};
}
fn intern[T](itr: &interner[T], val: &T) -> uint {
fn intern[@T](itr: &interner[T], val: &T) -> uint {
alt itr.map.find(val) {
some(idx) { ret idx; }
none. {

View file

@ -41,7 +41,7 @@ fn hash_def(d: &ast::def_id) -> uint {
ret h;
}
fn new_def_hash[V]() -> std::map::hashmap[ast::def_id, V] {
fn new_def_hash[@V]() -> std::map::hashmap[ast::def_id, V] {
let hasher: std::map::hashfn[ast::def_id] = hash_def;
let eqer: std::map::eqfn[ast::def_id] = def_eq;
ret std::map::mk_hashmap[ast::def_id, V](hasher, eqer);