fix classes and parameterized ifaces; remove needless self check

ref #1726, #2434
This commit is contained in:
Niko Matsakis
2012-05-24 06:20:46 -07:00
parent bd573becf5
commit a3be0b1054
7 changed files with 39 additions and 78 deletions

View File

@@ -192,8 +192,6 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
bind middle::check_loop::check_crate(ty_cx, crate));
time(time_passes, "alt checking",
bind middle::check_alt::check_crate(ty_cx, crate));
time(time_passes, "self checking",
bind middle::check_self::check_crate(ty_cx, crate));
time(time_passes, "typestate checking",
bind middle::tstate::ck::check_crate(ty_cx, crate));
let (root_map, mutbl_map) = time(

View File

@@ -1,60 +0,0 @@
/*
This module checks that within a class, "self" doesn't escape.
That is, it rejects any class in which "self" occurs other than
as the left-hand side of a field reference.
*/
import syntax::ast::*;
import syntax::visit::*;
import driver::session::session;
import std::map::hashmap;
import resolve::def_map;
fn check_crate(cx: ty::ctxt, crate: @crate) {
visit_crate(*crate, cx, mk_vt(@{
visit_item: bind check_item(_, _, _)
with *default_visitor()
}));
cx.sess.abort_if_errors();
}
fn check_item(it: @item, &&cx: ty::ctxt, &&_v: vt<ty::ctxt>) {
alt it.node {
item_class(*) {
visit_item(it, cx, check_self_visitor());
}
_ {}
}
}
fn check_self_visitor() -> vt<ty::ctxt> {
mk_vt(@{
visit_expr: bind check_self_expr(_, _, _)
with *default_visitor()
})
}
fn check_self_expr(e: @expr, &&cx: ty::ctxt, &&v: vt<ty::ctxt>) {
alt e.node {
expr_field(@{node: expr_path(p),_},_,_) {
// self is ok here; don't descend
}
expr_path(_) {
alt cx.def_map.find(e.id) {
some(def_self(_)) {
cx.sess.span_err(e.span, "can't return self or store \
it in a data structure");
}
_ {}
}
}
_ { visit_expr(e, cx, v); }
}
}
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:

View File

@@ -359,8 +359,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
// Write the class type
let tpt = ty_of_item(ccx, it);
write_ty_to_tcx(tcx, it.id, tpt.ty);
tcx.tcache.insert(local_def(it.id), {bounds: tpt.bounds,
rp: rp, ty: tpt.ty});
tcx.tcache.insert(local_def(it.id), tpt);
// Write the ctor type
let t_ctor =
ty::mk_fn(
@@ -416,13 +415,17 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
for ifaces.each { |ifce|
check_methods_against_iface(ccx, tps, rp, selfty,
ifce, methods);
let t = ty::node_id_to_type(tcx, ifce.id);
// FIXME: This assumes classes only implement
// non-parameterized ifaces. add a test case for
// a class implementing a parameterized iface.
// -- tjc (#1726)
tcx.tcache.insert(local_def(ifce.id), no_params(t));
// FIXME #2434---this is somewhat bogus, but it seems that
// the id of iface_ref is also the id of the impl, and so
// we want to store the "self type" of the impl---in this
// case, the class. The reason I say this is somewhat
// bogus (and should be refactored) is that the tcache
// stores the class type for ifce.id but the node_type
// table stores the iface type. Weird. Probably just
// adding a "self type" table rather than overloading the
// tcache would be ok, or else adding more than one id.
tcx.tcache.insert(local_def(ifce.id), tpt);
}
}
_ {

View File

@@ -68,7 +68,6 @@ mod middle {
mod check_loop;
mod check_alt;
mod check_const;
mod check_self;
mod lint;
mod borrowck;
mod alias;