Clean up some FIXMEs in middle:: modules
Rename all TODOs to FIXMEs
This commit is contained in:
parent
92a45f5582
commit
ff927f18f5
2 changed files with 86 additions and 122 deletions
|
@ -1359,17 +1359,14 @@ fn field_idx(id: ast::ident, fields: [field]) -> option<uint> {
|
|||
}
|
||||
|
||||
fn get_field(rec_ty: t, id: ast::ident) -> field {
|
||||
alt vec::find(get_fields(rec_ty), {|f| str::eq(f.ident, id) }) {
|
||||
alt check vec::find(get_fields(rec_ty), {|f| str::eq(f.ident, id) }) {
|
||||
some(f) { f }
|
||||
_ { fail #fmt("get_field: bad field id %s", id); }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: could have a precondition instead of failing
|
||||
fn get_fields(rec_ty:t) -> [field] {
|
||||
alt get(rec_ty).struct {
|
||||
alt check get(rec_ty).struct {
|
||||
ty_rec(fields) { fields }
|
||||
_ { fail "get_fields called on non-record type"; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2080,14 +2077,11 @@ mod unify {
|
|||
let err = terr_record_size(expected_len, actual_len);
|
||||
ret ures_err(err);
|
||||
}
|
||||
// TODO: implement an iterator that can iterate over
|
||||
// two arrays simultaneously.
|
||||
|
||||
let result_fields: [field] = [];
|
||||
let i = 0u;
|
||||
while i < expected_len {
|
||||
let expected_field = expected_fields[i];
|
||||
let actual_field = actual_fields[i];
|
||||
let result_fields = [], i = 0u;
|
||||
while i < actual_len {
|
||||
let expected_field = expected_fields[i],
|
||||
actual_field = actual_fields[i];
|
||||
let u_mut = unify_mut(expected_field.mt.mutbl,
|
||||
actual_field.mt.mutbl,
|
||||
variance);
|
||||
|
@ -2127,19 +2121,13 @@ mod unify {
|
|||
let err = terr_tuple_size(expected_len, actual_len);
|
||||
ret ures_err(err);
|
||||
}
|
||||
// TODO: implement an iterator that can iterate over
|
||||
// two arrays simultaneously.
|
||||
|
||||
let result_elems = [];
|
||||
let i = 0u;
|
||||
while i < expected_len {
|
||||
let expected_elem = expected_elems[i];
|
||||
let actual_elem = actual_elems[i];
|
||||
let result = unify_step(
|
||||
cx, expected_elem, actual_elem, variance);
|
||||
alt result {
|
||||
let result_elems = [], i = 0u;
|
||||
while i < actual_len {
|
||||
alt unify_step(cx, expected_elems[i], actual_elems[i],
|
||||
variance) {
|
||||
ures_ok(rty) { result_elems += [rty]; }
|
||||
_ { ret result; }
|
||||
r { ret r; }
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
|
|
|
@ -285,9 +285,6 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
|
|||
}
|
||||
fn instantiate(tcx: ty::ctxt, sp: span, mode: mode,
|
||||
id: ast::def_id, args: [@ast::ty]) -> ty::t {
|
||||
// TODO: maybe record cname chains so we can do
|
||||
// "foo = int" like OCaml?
|
||||
|
||||
let ty_param_bounds_and_ty = getter(tcx, mode, id);
|
||||
if vec::len(*ty_param_bounds_and_ty.bounds) == 0u {
|
||||
ret ty_param_bounds_and_ty.ty;
|
||||
|
@ -783,22 +780,14 @@ fn fixup_self_in_method_ty(cx: ty::ctxt, mty: ty::t, m_substs: [ty::t],
|
|||
//
|
||||
// We then annotate the AST with the resulting types and return the annotated
|
||||
// AST, along with a table mapping item IDs to their types.
|
||||
//
|
||||
// TODO: This logic is quite convoluted; it's a relic of the time when we
|
||||
// actually wrote types directly into the AST and didn't have a type cache.
|
||||
// Could use some cleanup. Consider topologically sorting in phase (1) above.
|
||||
mod collect {
|
||||
type ctxt = {tcx: ty::ctxt};
|
||||
|
||||
fn get_enum_variant_types(cx: @ctxt, enum_ty: ty::t,
|
||||
variants: [ast::variant],
|
||||
ty_params: [ast::ty_param]) {
|
||||
fn get_enum_variant_types(tcx: ty::ctxt, enum_ty: ty::t,
|
||||
variants: [ast::variant],
|
||||
ty_params: [ast::ty_param]) {
|
||||
// Create a set of parameter types shared among all the variants.
|
||||
|
||||
for variant: ast::variant in variants {
|
||||
for variant in variants {
|
||||
// Nullary enum constructors get turned into constants; n-ary enum
|
||||
// constructors get turned into functions.
|
||||
|
||||
let result_ty = if vec::len(variant.node.args) == 0u {
|
||||
enum_ty
|
||||
} else {
|
||||
|
@ -806,19 +795,19 @@ mod collect {
|
|||
// should be called to resolve named types.
|
||||
let args: [arg] = [];
|
||||
for va: ast::variant_arg in variant.node.args {
|
||||
let arg_ty = ast_ty_to_ty(cx.tcx, m_collect, va.ty);
|
||||
let arg_ty = ast_ty_to_ty(tcx, m_collect, va.ty);
|
||||
args += [{mode: ast::expl(ast::by_copy), ty: arg_ty}];
|
||||
}
|
||||
// FIXME: this will be different for constrained types
|
||||
ty::mk_fn(cx.tcx,
|
||||
ty::mk_fn(tcx,
|
||||
{proto: ast::proto_box,
|
||||
inputs: args, output: enum_ty,
|
||||
ret_style: ast::return_val, constraints: []})
|
||||
};
|
||||
let tpt = {bounds: ty_param_bounds(cx.tcx, m_collect, ty_params),
|
||||
let tpt = {bounds: ty_param_bounds(tcx, m_collect, ty_params),
|
||||
ty: result_ty};
|
||||
cx.tcx.tcache.insert(local_def(variant.node.id), tpt);
|
||||
write_ty(cx.tcx, variant.node.id, result_ty);
|
||||
tcx.tcache.insert(local_def(variant.node.id), tpt);
|
||||
write_ty(tcx, variant.node.id, result_ty);
|
||||
}
|
||||
}
|
||||
fn ensure_iface_methods(tcx: ty::ctxt, id: ast::node_id) {
|
||||
|
@ -830,7 +819,7 @@ mod collect {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn convert_class_item(cx: @ctxt, ci: ast::class_member) {
|
||||
fn convert_class_item(tcx: ty::ctxt, ci: ast::class_member) {
|
||||
/* we want to do something here, b/c within the
|
||||
scope of the class, it's ok to refer to fields &
|
||||
methods unqualified */
|
||||
|
@ -839,76 +828,76 @@ mod collect {
|
|||
class. outside the class, it's done with expr_field */
|
||||
alt ci {
|
||||
ast::instance_var(_,t,_,id) {
|
||||
let tt = ast_ty_to_ty(cx.tcx, m_collect, t);
|
||||
write_ty(cx.tcx, id, tt);
|
||||
let tt = ast_ty_to_ty(tcx, m_collect, t);
|
||||
write_ty(tcx, id, tt);
|
||||
}
|
||||
ast::class_method(it) { convert(cx, it); }
|
||||
ast::class_method(it) { convert(tcx, it); }
|
||||
}
|
||||
}
|
||||
fn convert(cx: @ctxt, it: @ast::item) {
|
||||
fn convert(tcx: ty::ctxt, it: @ast::item) {
|
||||
alt it.node {
|
||||
// These don't define types.
|
||||
ast::item_mod(_) | ast::item_native_mod(_) {}
|
||||
ast::item_enum(variants, ty_params) {
|
||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
||||
write_ty(cx.tcx, it.id, tpt.ty);
|
||||
get_enum_variant_types(cx, tpt.ty, variants, ty_params);
|
||||
let tpt = ty_of_item(tcx, m_collect, it);
|
||||
write_ty(tcx, it.id, tpt.ty);
|
||||
get_enum_variant_types(tcx, tpt.ty, variants, ty_params);
|
||||
}
|
||||
ast::item_impl(tps, ifce, selfty, ms) {
|
||||
let i_bounds = ty_param_bounds(cx.tcx, m_collect, tps);
|
||||
let i_bounds = ty_param_bounds(tcx, m_collect, tps);
|
||||
let my_methods = [];
|
||||
for m in ms {
|
||||
let bounds = ty_param_bounds(cx.tcx, m_collect, m.tps);
|
||||
let mty = ty_of_method(cx.tcx, m_collect, m);
|
||||
let bounds = ty_param_bounds(tcx, m_collect, m.tps);
|
||||
let mty = ty_of_method(tcx, m_collect, m);
|
||||
my_methods += [{mty: mty, id: m.id, span: m.span}];
|
||||
let fty = ty::mk_fn(cx.tcx, mty.fty);
|
||||
cx.tcx.tcache.insert(local_def(m.id),
|
||||
let fty = ty::mk_fn(tcx, mty.fty);
|
||||
tcx.tcache.insert(local_def(m.id),
|
||||
{bounds: @(*i_bounds + *bounds),
|
||||
ty: fty});
|
||||
write_ty(cx.tcx, m.id, fty);
|
||||
write_ty(tcx, m.id, fty);
|
||||
}
|
||||
let selfty = ast_ty_to_ty(cx.tcx, m_collect, selfty);
|
||||
write_ty(cx.tcx, it.id, selfty);
|
||||
let selfty = ast_ty_to_ty(tcx, m_collect, selfty);
|
||||
write_ty(tcx, it.id, selfty);
|
||||
alt ifce {
|
||||
some(t) {
|
||||
let iface_ty = ast_ty_to_ty(cx.tcx, m_collect, t);
|
||||
cx.tcx.tcache.insert(local_def(it.id),
|
||||
let iface_ty = ast_ty_to_ty(tcx, m_collect, t);
|
||||
tcx.tcache.insert(local_def(it.id),
|
||||
{bounds: i_bounds, ty: iface_ty});
|
||||
alt ty::get(iface_ty).struct {
|
||||
ty::ty_iface(did, tys) {
|
||||
if did.crate == ast::local_crate {
|
||||
ensure_iface_methods(cx.tcx, did.node);
|
||||
ensure_iface_methods(tcx, did.node);
|
||||
}
|
||||
for if_m in *ty::iface_methods(cx.tcx, did) {
|
||||
for if_m in *ty::iface_methods(tcx, did) {
|
||||
alt vec::find(my_methods,
|
||||
{|m| if_m.ident == m.mty.ident}) {
|
||||
some({mty: m, id, span}) {
|
||||
if m.purity != if_m.purity {
|
||||
cx.tcx.sess.span_err(
|
||||
tcx.sess.span_err(
|
||||
span, "method `" + m.ident + "`'s purity \
|
||||
not match the iface method's \
|
||||
purity");
|
||||
}
|
||||
let mt = compare_impl_method(
|
||||
cx.tcx, span, m, vec::len(tps), if_m, tys,
|
||||
tcx, span, m, vec::len(tps), if_m, tys,
|
||||
selfty);
|
||||
let old = cx.tcx.tcache.get(local_def(id));
|
||||
let old = tcx.tcache.get(local_def(id));
|
||||
if old.ty != mt {
|
||||
cx.tcx.tcache.insert(local_def(id),
|
||||
tcx.tcache.insert(local_def(id),
|
||||
{bounds: old.bounds,
|
||||
ty: mt});
|
||||
write_ty(cx.tcx, id, mt);
|
||||
write_ty(tcx, id, mt);
|
||||
}
|
||||
}
|
||||
none {
|
||||
cx.tcx.sess.span_err(t.span, "missing method `" +
|
||||
tcx.sess.span_err(t.span, "missing method `" +
|
||||
if_m.ident + "`");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ {
|
||||
cx.tcx.sess.span_fatal(t.span, "can only implement \
|
||||
tcx.sess.span_fatal(t.span, "can only implement \
|
||||
interface types");
|
||||
}
|
||||
}
|
||||
|
@ -917,81 +906,76 @@ mod collect {
|
|||
}
|
||||
}
|
||||
ast::item_res(decl, tps, _, dtor_id, ctor_id) {
|
||||
let {bounds, params} = mk_ty_params(cx.tcx, tps);
|
||||
let t_arg = ty_of_arg(cx.tcx, m_collect, decl.inputs[0]);
|
||||
let t_res = ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty,
|
||||
let {bounds, params} = mk_ty_params(tcx, tps);
|
||||
let t_arg = ty_of_arg(tcx, m_collect, decl.inputs[0]);
|
||||
let t_res = ty::mk_res(tcx, local_def(it.id), t_arg.ty,
|
||||
params);
|
||||
let t_ctor = ty::mk_fn(cx.tcx, {
|
||||
let t_ctor = ty::mk_fn(tcx, {
|
||||
proto: ast::proto_box,
|
||||
inputs: [{mode: ast::expl(ast::by_copy) with t_arg}],
|
||||
output: t_res,
|
||||
ret_style: ast::return_val, constraints: []
|
||||
});
|
||||
let t_dtor = ty::mk_fn(cx.tcx, {
|
||||
let t_dtor = ty::mk_fn(tcx, {
|
||||
proto: ast::proto_box,
|
||||
inputs: [t_arg], output: ty::mk_nil(cx.tcx),
|
||||
inputs: [t_arg], output: ty::mk_nil(tcx),
|
||||
ret_style: ast::return_val, constraints: []
|
||||
});
|
||||
write_ty(cx.tcx, it.id, t_res);
|
||||
write_ty(cx.tcx, ctor_id, t_ctor);
|
||||
cx.tcx.tcache.insert(local_def(ctor_id),
|
||||
write_ty(tcx, it.id, t_res);
|
||||
write_ty(tcx, ctor_id, t_ctor);
|
||||
tcx.tcache.insert(local_def(ctor_id),
|
||||
{bounds: bounds, ty: t_ctor});
|
||||
write_ty(cx.tcx, dtor_id, t_dtor);
|
||||
write_ty(tcx, dtor_id, t_dtor);
|
||||
}
|
||||
ast::item_iface(_, ms) {
|
||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
||||
write_ty(cx.tcx, it.id, tpt.ty);
|
||||
ensure_iface_methods(cx.tcx, it.id);
|
||||
let tpt = ty_of_item(tcx, m_collect, it);
|
||||
write_ty(tcx, it.id, tpt.ty);
|
||||
ensure_iface_methods(tcx, it.id);
|
||||
}
|
||||
ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) {
|
||||
// Write the class type
|
||||
let {bounds,params} = mk_ty_params(cx.tcx, tps);
|
||||
let class_ty = ty::mk_class(cx.tcx, local_def(it.id), params);
|
||||
let {bounds,params} = mk_ty_params(tcx, tps);
|
||||
let class_ty = ty::mk_class(tcx, local_def(it.id), params);
|
||||
let tpt = {bounds: bounds, ty: class_ty};
|
||||
cx.tcx.tcache.insert(local_def(it.id), tpt);
|
||||
write_ty(cx.tcx, it.id, class_ty);
|
||||
tcx.tcache.insert(local_def(it.id), tpt);
|
||||
write_ty(tcx, it.id, class_ty);
|
||||
// Write the ctor type
|
||||
let t_ctor = ty::mk_fn(cx.tcx,
|
||||
ty_of_fn_decl(cx.tcx, m_collect,
|
||||
let t_ctor = ty::mk_fn(tcx,
|
||||
ty_of_fn_decl(tcx, m_collect,
|
||||
ast::proto_any, ctor_decl));
|
||||
write_ty(cx.tcx, ctor_id, t_ctor);
|
||||
cx.tcx.tcache.insert(local_def(ctor_id),
|
||||
write_ty(tcx, ctor_id, t_ctor);
|
||||
tcx.tcache.insert(local_def(ctor_id),
|
||||
{bounds: bounds, ty: t_ctor});
|
||||
/* FIXME: check for proper public/privateness */
|
||||
// Write the type of each of the members
|
||||
for m in members {
|
||||
convert_class_item(cx, m.node.decl);
|
||||
convert_class_item(tcx, m.node.decl);
|
||||
}
|
||||
}
|
||||
_ {
|
||||
// This call populates the type cache with the converted type
|
||||
// of the item in passing. All we have to do here is to write
|
||||
// it into the node type table.
|
||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
||||
write_ty(cx.tcx, it.id, tpt.ty);
|
||||
let tpt = ty_of_item(tcx, m_collect, it);
|
||||
write_ty(tcx, it.id, tpt.ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn convert_native(cx: @ctxt, i: @ast::native_item) {
|
||||
fn convert_native(tcx: ty::ctxt, i: @ast::native_item) {
|
||||
// As above, this call populates the type table with the converted
|
||||
// type of the native item. We simply write it into the node type
|
||||
// table.
|
||||
let tpt = ty_of_native_item(cx.tcx, m_collect, i);
|
||||
let tpt = ty_of_native_item(tcx, m_collect, i);
|
||||
alt i.node {
|
||||
ast::native_item_fn(_, _) {
|
||||
write_ty(cx.tcx, i.id, tpt.ty);
|
||||
}
|
||||
ast::native_item_fn(_, _) { write_ty(tcx, i.id, tpt.ty); }
|
||||
}
|
||||
}
|
||||
fn collect_item_types(tcx: ty::ctxt, crate: @ast::crate) {
|
||||
let cx = @{tcx: tcx};
|
||||
let visit =
|
||||
visit::mk_simple_visitor(@{visit_item: bind convert(cx, _),
|
||||
visit_native_item:
|
||||
bind convert_native(cx, _)
|
||||
with
|
||||
*visit::default_simple_visitor()});
|
||||
visit::visit_crate(*crate, (), visit);
|
||||
visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
|
||||
visit_item: bind convert(tcx, _),
|
||||
visit_native_item: bind convert_native(tcx, _)
|
||||
with *visit::default_simple_visitor()
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1459,17 +1443,12 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
|
|||
demand::with_substs(fcx, pat.span, expected, ctor_ty,
|
||||
expected_tps);
|
||||
// Get the number of arguments in this enum variant.
|
||||
let arg_types =
|
||||
variant_arg_types(fcx.ccx, pat.span, v_def_ids.var,
|
||||
expected_tps);
|
||||
let subpats_len = vec::len::<@ast::pat>(subpats);
|
||||
if vec::len::<ty::t>(arg_types) > 0u {
|
||||
let arg_types = variant_arg_types(fcx.ccx, pat.span,
|
||||
v_def_ids.var, expected_tps);
|
||||
let subpats_len = subpats.len(), arg_len = arg_types.len();
|
||||
if arg_len > 0u {
|
||||
// N-ary variant.
|
||||
let arg_len = vec::len::<ty::t>(arg_types);
|
||||
if arg_len != subpats_len {
|
||||
// TODO: note definition of enum variant
|
||||
// TODO (issue #448): Wrap a #fmt string over multiple
|
||||
// lines...
|
||||
let s = #fmt["this pattern has %u field%s, but the \
|
||||
corresponding variant has %u field%s",
|
||||
subpats_len,
|
||||
|
@ -1483,7 +1462,6 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
|
|||
check_pat(fcx, map, subpat, arg_ty);
|
||||
}
|
||||
} else if subpats_len > 0u {
|
||||
// TODO: note definition of enum variant
|
||||
tcx.sess.span_err
|
||||
(pat.span, #fmt["this pattern has %u field%s, \
|
||||
but the corresponding \
|
||||
|
@ -1494,11 +1472,9 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
|
|||
}
|
||||
}
|
||||
_ {
|
||||
// FIXME: Switch expected and actual in this message? I
|
||||
// can never tell.
|
||||
tcx.sess.span_err
|
||||
(pat.span,
|
||||
#fmt["mismatched types: expected `%s` but found enum",
|
||||
#fmt["mismatched types: expected enum but found `%s`",
|
||||
ty_to_str(tcx, expected)]);
|
||||
}
|
||||
}
|
||||
|
@ -2536,7 +2512,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
// field
|
||||
// For now, this code assumes the class is defined in the local
|
||||
// crate
|
||||
// TODO: handle field references to classes in external crate
|
||||
// FIXME: handle field references to classes in external crate
|
||||
let err = "Class ID is not bound to a class";
|
||||
let field_ty = alt fcx.ccx.tcx.items.find(base_id.node) {
|
||||
some(ast_map::node_item(i,_)) {
|
||||
|
@ -2551,7 +2527,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
_ { fcx.ccx.tcx.sess.span_bug(expr.span, err); }
|
||||
};
|
||||
// (2) look up what field's type is, and return it
|
||||
// TODO: actually instantiate any type params
|
||||
// FIXME: actually instantiate any type params
|
||||
write_ty(tcx, id, field_ty);
|
||||
handled = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue