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 {
|
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 }
|
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] {
|
fn get_fields(rec_ty:t) -> [field] {
|
||||||
alt get(rec_ty).struct {
|
alt check get(rec_ty).struct {
|
||||||
ty_rec(fields) { fields }
|
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);
|
let err = terr_record_size(expected_len, actual_len);
|
||||||
ret ures_err(err);
|
ret ures_err(err);
|
||||||
}
|
}
|
||||||
// TODO: implement an iterator that can iterate over
|
|
||||||
// two arrays simultaneously.
|
|
||||||
|
|
||||||
let result_fields: [field] = [];
|
let result_fields = [], i = 0u;
|
||||||
let i = 0u;
|
while i < actual_len {
|
||||||
while i < expected_len {
|
let expected_field = expected_fields[i],
|
||||||
let expected_field = expected_fields[i];
|
actual_field = actual_fields[i];
|
||||||
let actual_field = actual_fields[i];
|
|
||||||
let u_mut = unify_mut(expected_field.mt.mutbl,
|
let u_mut = unify_mut(expected_field.mt.mutbl,
|
||||||
actual_field.mt.mutbl,
|
actual_field.mt.mutbl,
|
||||||
variance);
|
variance);
|
||||||
|
@ -2127,19 +2121,13 @@ mod unify {
|
||||||
let err = terr_tuple_size(expected_len, actual_len);
|
let err = terr_tuple_size(expected_len, actual_len);
|
||||||
ret ures_err(err);
|
ret ures_err(err);
|
||||||
}
|
}
|
||||||
// TODO: implement an iterator that can iterate over
|
|
||||||
// two arrays simultaneously.
|
|
||||||
|
|
||||||
let result_elems = [];
|
let result_elems = [], i = 0u;
|
||||||
let i = 0u;
|
while i < actual_len {
|
||||||
while i < expected_len {
|
alt unify_step(cx, expected_elems[i], actual_elems[i],
|
||||||
let expected_elem = expected_elems[i];
|
variance) {
|
||||||
let actual_elem = actual_elems[i];
|
|
||||||
let result = unify_step(
|
|
||||||
cx, expected_elem, actual_elem, variance);
|
|
||||||
alt result {
|
|
||||||
ures_ok(rty) { result_elems += [rty]; }
|
ures_ok(rty) { result_elems += [rty]; }
|
||||||
_ { ret result; }
|
r { ret r; }
|
||||||
}
|
}
|
||||||
i += 1u;
|
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,
|
fn instantiate(tcx: ty::ctxt, sp: span, mode: mode,
|
||||||
id: ast::def_id, args: [@ast::ty]) -> ty::t {
|
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);
|
let ty_param_bounds_and_ty = getter(tcx, mode, id);
|
||||||
if vec::len(*ty_param_bounds_and_ty.bounds) == 0u {
|
if vec::len(*ty_param_bounds_and_ty.bounds) == 0u {
|
||||||
ret ty_param_bounds_and_ty.ty;
|
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
|
// We then annotate the AST with the resulting types and return the annotated
|
||||||
// AST, along with a table mapping item IDs to their types.
|
// 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 {
|
mod collect {
|
||||||
type ctxt = {tcx: ty::ctxt};
|
fn get_enum_variant_types(tcx: ty::ctxt, enum_ty: ty::t,
|
||||||
|
variants: [ast::variant],
|
||||||
fn get_enum_variant_types(cx: @ctxt, enum_ty: ty::t,
|
ty_params: [ast::ty_param]) {
|
||||||
variants: [ast::variant],
|
|
||||||
ty_params: [ast::ty_param]) {
|
|
||||||
// Create a set of parameter types shared among all the variants.
|
// Create a set of parameter types shared among all the variants.
|
||||||
|
for variant in variants {
|
||||||
for variant: ast::variant in variants {
|
|
||||||
// Nullary enum constructors get turned into constants; n-ary enum
|
// Nullary enum constructors get turned into constants; n-ary enum
|
||||||
// constructors get turned into functions.
|
// constructors get turned into functions.
|
||||||
|
|
||||||
let result_ty = if vec::len(variant.node.args) == 0u {
|
let result_ty = if vec::len(variant.node.args) == 0u {
|
||||||
enum_ty
|
enum_ty
|
||||||
} else {
|
} else {
|
||||||
|
@ -806,19 +795,19 @@ mod collect {
|
||||||
// should be called to resolve named types.
|
// should be called to resolve named types.
|
||||||
let args: [arg] = [];
|
let args: [arg] = [];
|
||||||
for va: ast::variant_arg in variant.node.args {
|
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}];
|
args += [{mode: ast::expl(ast::by_copy), ty: arg_ty}];
|
||||||
}
|
}
|
||||||
// FIXME: this will be different for constrained types
|
// FIXME: this will be different for constrained types
|
||||||
ty::mk_fn(cx.tcx,
|
ty::mk_fn(tcx,
|
||||||
{proto: ast::proto_box,
|
{proto: ast::proto_box,
|
||||||
inputs: args, output: enum_ty,
|
inputs: args, output: enum_ty,
|
||||||
ret_style: ast::return_val, constraints: []})
|
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};
|
ty: result_ty};
|
||||||
cx.tcx.tcache.insert(local_def(variant.node.id), tpt);
|
tcx.tcache.insert(local_def(variant.node.id), tpt);
|
||||||
write_ty(cx.tcx, variant.node.id, result_ty);
|
write_ty(tcx, variant.node.id, result_ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn ensure_iface_methods(tcx: ty::ctxt, id: ast::node_id) {
|
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
|
/* we want to do something here, b/c within the
|
||||||
scope of the class, it's ok to refer to fields &
|
scope of the class, it's ok to refer to fields &
|
||||||
methods unqualified */
|
methods unqualified */
|
||||||
|
@ -839,76 +828,76 @@ mod collect {
|
||||||
class. outside the class, it's done with expr_field */
|
class. outside the class, it's done with expr_field */
|
||||||
alt ci {
|
alt ci {
|
||||||
ast::instance_var(_,t,_,id) {
|
ast::instance_var(_,t,_,id) {
|
||||||
let tt = ast_ty_to_ty(cx.tcx, m_collect, t);
|
let tt = ast_ty_to_ty(tcx, m_collect, t);
|
||||||
write_ty(cx.tcx, id, tt);
|
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 {
|
alt it.node {
|
||||||
// These don't define types.
|
// These don't define types.
|
||||||
ast::item_mod(_) | ast::item_native_mod(_) {}
|
ast::item_mod(_) | ast::item_native_mod(_) {}
|
||||||
ast::item_enum(variants, ty_params) {
|
ast::item_enum(variants, ty_params) {
|
||||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
let tpt = ty_of_item(tcx, m_collect, it);
|
||||||
write_ty(cx.tcx, it.id, tpt.ty);
|
write_ty(tcx, it.id, tpt.ty);
|
||||||
get_enum_variant_types(cx, tpt.ty, variants, ty_params);
|
get_enum_variant_types(tcx, tpt.ty, variants, ty_params);
|
||||||
}
|
}
|
||||||
ast::item_impl(tps, ifce, selfty, ms) {
|
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 = [];
|
let my_methods = [];
|
||||||
for m in ms {
|
for m in ms {
|
||||||
let bounds = ty_param_bounds(cx.tcx, m_collect, m.tps);
|
let bounds = ty_param_bounds(tcx, m_collect, m.tps);
|
||||||
let mty = ty_of_method(cx.tcx, m_collect, m);
|
let mty = ty_of_method(tcx, m_collect, m);
|
||||||
my_methods += [{mty: mty, id: m.id, span: m.span}];
|
my_methods += [{mty: mty, id: m.id, span: m.span}];
|
||||||
let fty = ty::mk_fn(cx.tcx, mty.fty);
|
let fty = ty::mk_fn(tcx, mty.fty);
|
||||||
cx.tcx.tcache.insert(local_def(m.id),
|
tcx.tcache.insert(local_def(m.id),
|
||||||
{bounds: @(*i_bounds + *bounds),
|
{bounds: @(*i_bounds + *bounds),
|
||||||
ty: fty});
|
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);
|
let selfty = ast_ty_to_ty(tcx, m_collect, selfty);
|
||||||
write_ty(cx.tcx, it.id, selfty);
|
write_ty(tcx, it.id, selfty);
|
||||||
alt ifce {
|
alt ifce {
|
||||||
some(t) {
|
some(t) {
|
||||||
let iface_ty = ast_ty_to_ty(cx.tcx, m_collect, t);
|
let iface_ty = ast_ty_to_ty(tcx, m_collect, t);
|
||||||
cx.tcx.tcache.insert(local_def(it.id),
|
tcx.tcache.insert(local_def(it.id),
|
||||||
{bounds: i_bounds, ty: iface_ty});
|
{bounds: i_bounds, ty: iface_ty});
|
||||||
alt ty::get(iface_ty).struct {
|
alt ty::get(iface_ty).struct {
|
||||||
ty::ty_iface(did, tys) {
|
ty::ty_iface(did, tys) {
|
||||||
if did.crate == ast::local_crate {
|
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,
|
alt vec::find(my_methods,
|
||||||
{|m| if_m.ident == m.mty.ident}) {
|
{|m| if_m.ident == m.mty.ident}) {
|
||||||
some({mty: m, id, span}) {
|
some({mty: m, id, span}) {
|
||||||
if m.purity != if_m.purity {
|
if m.purity != if_m.purity {
|
||||||
cx.tcx.sess.span_err(
|
tcx.sess.span_err(
|
||||||
span, "method `" + m.ident + "`'s purity \
|
span, "method `" + m.ident + "`'s purity \
|
||||||
not match the iface method's \
|
not match the iface method's \
|
||||||
purity");
|
purity");
|
||||||
}
|
}
|
||||||
let mt = compare_impl_method(
|
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);
|
selfty);
|
||||||
let old = cx.tcx.tcache.get(local_def(id));
|
let old = tcx.tcache.get(local_def(id));
|
||||||
if old.ty != mt {
|
if old.ty != mt {
|
||||||
cx.tcx.tcache.insert(local_def(id),
|
tcx.tcache.insert(local_def(id),
|
||||||
{bounds: old.bounds,
|
{bounds: old.bounds,
|
||||||
ty: mt});
|
ty: mt});
|
||||||
write_ty(cx.tcx, id, mt);
|
write_ty(tcx, id, mt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
none {
|
none {
|
||||||
cx.tcx.sess.span_err(t.span, "missing method `" +
|
tcx.sess.span_err(t.span, "missing method `" +
|
||||||
if_m.ident + "`");
|
if_m.ident + "`");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ {
|
_ {
|
||||||
cx.tcx.sess.span_fatal(t.span, "can only implement \
|
tcx.sess.span_fatal(t.span, "can only implement \
|
||||||
interface types");
|
interface types");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -917,81 +906,76 @@ mod collect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::item_res(decl, tps, _, dtor_id, ctor_id) {
|
ast::item_res(decl, tps, _, dtor_id, ctor_id) {
|
||||||
let {bounds, params} = mk_ty_params(cx.tcx, tps);
|
let {bounds, params} = mk_ty_params(tcx, tps);
|
||||||
let t_arg = ty_of_arg(cx.tcx, m_collect, decl.inputs[0]);
|
let t_arg = ty_of_arg(tcx, m_collect, decl.inputs[0]);
|
||||||
let t_res = ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty,
|
let t_res = ty::mk_res(tcx, local_def(it.id), t_arg.ty,
|
||||||
params);
|
params);
|
||||||
let t_ctor = ty::mk_fn(cx.tcx, {
|
let t_ctor = ty::mk_fn(tcx, {
|
||||||
proto: ast::proto_box,
|
proto: ast::proto_box,
|
||||||
inputs: [{mode: ast::expl(ast::by_copy) with t_arg}],
|
inputs: [{mode: ast::expl(ast::by_copy) with t_arg}],
|
||||||
output: t_res,
|
output: t_res,
|
||||||
ret_style: ast::return_val, constraints: []
|
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,
|
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: []
|
ret_style: ast::return_val, constraints: []
|
||||||
});
|
});
|
||||||
write_ty(cx.tcx, it.id, t_res);
|
write_ty(tcx, it.id, t_res);
|
||||||
write_ty(cx.tcx, ctor_id, t_ctor);
|
write_ty(tcx, ctor_id, t_ctor);
|
||||||
cx.tcx.tcache.insert(local_def(ctor_id),
|
tcx.tcache.insert(local_def(ctor_id),
|
||||||
{bounds: bounds, ty: t_ctor});
|
{bounds: bounds, ty: t_ctor});
|
||||||
write_ty(cx.tcx, dtor_id, t_dtor);
|
write_ty(tcx, dtor_id, t_dtor);
|
||||||
}
|
}
|
||||||
ast::item_iface(_, ms) {
|
ast::item_iface(_, ms) {
|
||||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
let tpt = ty_of_item(tcx, m_collect, it);
|
||||||
write_ty(cx.tcx, it.id, tpt.ty);
|
write_ty(tcx, it.id, tpt.ty);
|
||||||
ensure_iface_methods(cx.tcx, it.id);
|
ensure_iface_methods(tcx, it.id);
|
||||||
}
|
}
|
||||||
ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) {
|
ast::item_class(tps, members, ctor_id, ctor_decl, ctor_block) {
|
||||||
// Write the class type
|
// Write the class type
|
||||||
let {bounds,params} = mk_ty_params(cx.tcx, tps);
|
let {bounds,params} = mk_ty_params(tcx, tps);
|
||||||
let class_ty = ty::mk_class(cx.tcx, local_def(it.id), params);
|
let class_ty = ty::mk_class(tcx, local_def(it.id), params);
|
||||||
let tpt = {bounds: bounds, ty: class_ty};
|
let tpt = {bounds: bounds, ty: class_ty};
|
||||||
cx.tcx.tcache.insert(local_def(it.id), tpt);
|
tcx.tcache.insert(local_def(it.id), tpt);
|
||||||
write_ty(cx.tcx, it.id, class_ty);
|
write_ty(tcx, it.id, class_ty);
|
||||||
// Write the ctor type
|
// Write the ctor type
|
||||||
let t_ctor = ty::mk_fn(cx.tcx,
|
let t_ctor = ty::mk_fn(tcx,
|
||||||
ty_of_fn_decl(cx.tcx, m_collect,
|
ty_of_fn_decl(tcx, m_collect,
|
||||||
ast::proto_any, ctor_decl));
|
ast::proto_any, ctor_decl));
|
||||||
write_ty(cx.tcx, ctor_id, t_ctor);
|
write_ty(tcx, ctor_id, t_ctor);
|
||||||
cx.tcx.tcache.insert(local_def(ctor_id),
|
tcx.tcache.insert(local_def(ctor_id),
|
||||||
{bounds: bounds, ty: t_ctor});
|
{bounds: bounds, ty: t_ctor});
|
||||||
/* FIXME: check for proper public/privateness */
|
/* FIXME: check for proper public/privateness */
|
||||||
// Write the type of each of the members
|
// Write the type of each of the members
|
||||||
for m in 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
|
// This call populates the type cache with the converted type
|
||||||
// of the item in passing. All we have to do here is to write
|
// of the item in passing. All we have to do here is to write
|
||||||
// it into the node type table.
|
// it into the node type table.
|
||||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
let tpt = ty_of_item(tcx, m_collect, it);
|
||||||
write_ty(cx.tcx, it.id, tpt.ty);
|
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
|
// As above, this call populates the type table with the converted
|
||||||
// type of the native item. We simply write it into the node type
|
// type of the native item. We simply write it into the node type
|
||||||
// table.
|
// 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 {
|
alt i.node {
|
||||||
ast::native_item_fn(_, _) {
|
ast::native_item_fn(_, _) { write_ty(tcx, i.id, tpt.ty); }
|
||||||
write_ty(cx.tcx, i.id, tpt.ty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn collect_item_types(tcx: ty::ctxt, crate: @ast::crate) {
|
fn collect_item_types(tcx: ty::ctxt, crate: @ast::crate) {
|
||||||
let cx = @{tcx: tcx};
|
visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
|
||||||
let visit =
|
visit_item: bind convert(tcx, _),
|
||||||
visit::mk_simple_visitor(@{visit_item: bind convert(cx, _),
|
visit_native_item: bind convert_native(tcx, _)
|
||||||
visit_native_item:
|
with *visit::default_simple_visitor()
|
||||||
bind convert_native(cx, _)
|
}));
|
||||||
with
|
|
||||||
*visit::default_simple_visitor()});
|
|
||||||
visit::visit_crate(*crate, (), visit);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
demand::with_substs(fcx, pat.span, expected, ctor_ty,
|
||||||
expected_tps);
|
expected_tps);
|
||||||
// Get the number of arguments in this enum variant.
|
// Get the number of arguments in this enum variant.
|
||||||
let arg_types =
|
let arg_types = variant_arg_types(fcx.ccx, pat.span,
|
||||||
variant_arg_types(fcx.ccx, pat.span, v_def_ids.var,
|
v_def_ids.var, expected_tps);
|
||||||
expected_tps);
|
let subpats_len = subpats.len(), arg_len = arg_types.len();
|
||||||
let subpats_len = vec::len::<@ast::pat>(subpats);
|
if arg_len > 0u {
|
||||||
if vec::len::<ty::t>(arg_types) > 0u {
|
|
||||||
// N-ary variant.
|
// N-ary variant.
|
||||||
let arg_len = vec::len::<ty::t>(arg_types);
|
|
||||||
if arg_len != subpats_len {
|
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 \
|
let s = #fmt["this pattern has %u field%s, but the \
|
||||||
corresponding variant has %u field%s",
|
corresponding variant has %u field%s",
|
||||||
subpats_len,
|
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);
|
check_pat(fcx, map, subpat, arg_ty);
|
||||||
}
|
}
|
||||||
} else if subpats_len > 0u {
|
} else if subpats_len > 0u {
|
||||||
// TODO: note definition of enum variant
|
|
||||||
tcx.sess.span_err
|
tcx.sess.span_err
|
||||||
(pat.span, #fmt["this pattern has %u field%s, \
|
(pat.span, #fmt["this pattern has %u field%s, \
|
||||||
but the corresponding \
|
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
|
tcx.sess.span_err
|
||||||
(pat.span,
|
(pat.span,
|
||||||
#fmt["mismatched types: expected `%s` but found enum",
|
#fmt["mismatched types: expected enum but found `%s`",
|
||||||
ty_to_str(tcx, expected)]);
|
ty_to_str(tcx, expected)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2536,7 +2512,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
||||||
// field
|
// field
|
||||||
// For now, this code assumes the class is defined in the local
|
// For now, this code assumes the class is defined in the local
|
||||||
// crate
|
// 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 err = "Class ID is not bound to a class";
|
||||||
let field_ty = alt fcx.ccx.tcx.items.find(base_id.node) {
|
let field_ty = alt fcx.ccx.tcx.items.find(base_id.node) {
|
||||||
some(ast_map::node_item(i,_)) {
|
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); }
|
_ { fcx.ccx.tcx.sess.span_bug(expr.span, err); }
|
||||||
};
|
};
|
||||||
// (2) look up what field's type is, and return it
|
// (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);
|
write_ty(tcx, id, field_ty);
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue