fix classes and parameterized ifaces; remove needless self check
ref #1726, #2434
This commit is contained in:
parent
bd573becf5
commit
a3be0b1054
7 changed files with 39 additions and 78 deletions
|
@ -192,8 +192,6 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||||
bind middle::check_loop::check_crate(ty_cx, crate));
|
bind middle::check_loop::check_crate(ty_cx, crate));
|
||||||
time(time_passes, "alt checking",
|
time(time_passes, "alt checking",
|
||||||
bind middle::check_alt::check_crate(ty_cx, crate));
|
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",
|
time(time_passes, "typestate checking",
|
||||||
bind middle::tstate::ck::check_crate(ty_cx, crate));
|
bind middle::tstate::ck::check_crate(ty_cx, crate));
|
||||||
let (root_map, mutbl_map) = time(
|
let (root_map, mutbl_map) = time(
|
||||||
|
|
|
@ -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:
|
|
|
@ -359,8 +359,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
|
||||||
// Write the class type
|
// Write the class type
|
||||||
let tpt = ty_of_item(ccx, it);
|
let tpt = ty_of_item(ccx, it);
|
||||||
write_ty_to_tcx(tcx, it.id, tpt.ty);
|
write_ty_to_tcx(tcx, it.id, tpt.ty);
|
||||||
tcx.tcache.insert(local_def(it.id), {bounds: tpt.bounds,
|
tcx.tcache.insert(local_def(it.id), tpt);
|
||||||
rp: rp, ty: tpt.ty});
|
|
||||||
// Write the ctor type
|
// Write the ctor type
|
||||||
let t_ctor =
|
let t_ctor =
|
||||||
ty::mk_fn(
|
ty::mk_fn(
|
||||||
|
@ -416,13 +415,17 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
|
||||||
for ifaces.each { |ifce|
|
for ifaces.each { |ifce|
|
||||||
check_methods_against_iface(ccx, tps, rp, selfty,
|
check_methods_against_iface(ccx, tps, rp, selfty,
|
||||||
ifce, methods);
|
ifce, methods);
|
||||||
let t = ty::node_id_to_type(tcx, ifce.id);
|
|
||||||
|
|
||||||
// FIXME: This assumes classes only implement
|
// FIXME #2434---this is somewhat bogus, but it seems that
|
||||||
// non-parameterized ifaces. add a test case for
|
// the id of iface_ref is also the id of the impl, and so
|
||||||
// a class implementing a parameterized iface.
|
// we want to store the "self type" of the impl---in this
|
||||||
// -- tjc (#1726)
|
// case, the class. The reason I say this is somewhat
|
||||||
tcx.tcache.insert(local_def(ifce.id), no_params(t));
|
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ {
|
_ {
|
||||||
|
|
|
@ -68,7 +68,6 @@ mod middle {
|
||||||
mod check_loop;
|
mod check_loop;
|
||||||
mod check_alt;
|
mod check_alt;
|
||||||
mod check_const;
|
mod check_const;
|
||||||
mod check_self;
|
|
||||||
mod lint;
|
mod lint;
|
||||||
mod borrowck;
|
mod borrowck;
|
||||||
mod alias;
|
mod alias;
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
class cat {
|
|
||||||
fn kitty() -> cat { self } //! ERROR: can't return self or store it in a data structure
|
|
||||||
new() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
23
src/test/run-pass/class-iface-bounded-param.rs
Normal file
23
src/test/run-pass/class-iface-bounded-param.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use std;
|
||||||
|
import std::map::{map, hashmap, int_hash};
|
||||||
|
|
||||||
|
class keys<K: copy, V: copy, M: copy map<K,V>>
|
||||||
|
implements iter::base_iter<K> {
|
||||||
|
|
||||||
|
let map: M;
|
||||||
|
|
||||||
|
new(map: M) {
|
||||||
|
self.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn each(blk: fn(K) -> bool) { self.map.each { |k, _v| blk(k)} }
|
||||||
|
fn size_hint() -> option<uint> { some(self.map.size()) }
|
||||||
|
fn eachi(blk: fn(uint, K) -> bool) { iter::eachi(self, blk) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let m = int_hash();
|
||||||
|
m.insert(1, 2);
|
||||||
|
m.insert(3, 4);
|
||||||
|
assert iter::to_vec(keys(m)) == [1, 3];
|
||||||
|
}
|
|
@ -35,10 +35,14 @@ class cat implements noisy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_speak<C: noisy>(c: C) {
|
||||||
|
c.speak();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let nyan = cat(0u, 2, "nyan");
|
let nyan = cat(0u, 2, "nyan");
|
||||||
nyan.eat();
|
nyan.eat();
|
||||||
assert(!nyan.eat());
|
assert(!nyan.eat());
|
||||||
uint::range(1u, 10u, {|_i| nyan.speak(); });
|
uint::range(1u, 10u, {|_i| make_speak(nyan); });
|
||||||
assert(nyan.eat());
|
assert(nyan.eat());
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue