All field or method references within a class must begin with "self." now.
A bare reference to a field or method in the same class will no longer
typecheck.
ast::def_class(did) {
ast::def_class(did.tr(xcx))
}
- ast::def_class_field(did0, did1) {
- ast::def_class_field(did0.tr(xcx), did1.tr(xcx))
- }
- ast::def_class_method(did0, did1) {
- ast::def_class_method(did0.tr(xcx), did1.tr(xcx))
- }
ast::def_region(nid) { ast::def_region(xcx.tr_id(nid)) }
}
}
fn is_illegal_to_modify_def(cx: @ctx, def: def, msg: msg) -> option<str> {
alt def {
def_fn(_, _) | def_mod(_) | def_native_mod(_) | def_const(_) |
- def_use(_) | def_class_method(_,_) {
+ def_use(_) {
some("static item")
}
def_arg(_, m) {
}
def_binding(_) { some("binding") }
- def_class_field(parent,fld) {
- if option::is_none(cx.in_ctor) {
- /* Enforce mutability *unless* we're inside a ctor */
- alt ty::lookup_class_field(cx.tcx, parent, fld).mutability {
- class_mutable { none }
- class_immutable { some("immutable class field") }
- }
- }
- else {
- none
- }
- }
_ { none }
}
}
mie_view_item(ident, node_id, span),
mie_import_ident(node_id, span),
mie_item(@ast::item),
- mie_class_item(node_id, /* parent class name */
- @ast::class_member), /* class member */
mie_native_item(@ast::native_item),
mie_enum_variant(/* variant index */uint,
/*parts of enum item*/ [variant],
ret some(ast::def_fn(local_def(ctor.node.id),
ast::impure_fn));
}
- if ns == ns_val {
- ret lookup_in_class(local_def(it.id), members, name);
- }
// FIXME: AST allows other items to appear in a class,
// but that might not be wise
}
}
}
-/*
- FIXME: not sure about this code. maybe this should be handled
- using the mod_index stuff
- */
-fn lookup_in_class(parent_id: def_id,
- members: [@class_member], name: ident)
- -> option<def> {
- for m in members {
- alt m.node {
- instance_var(v_name,_,_,id,_) {
- if v_name == name {
- ret some(def_class_field(parent_id, local_def(id)));
- }
- }
- class_method(i) {
- if i.ident == name {
- ret some(def_class_method(parent_id, local_def(i.id)));
- }
- }
- }
- }
- ret none;
-}
-
fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint,
loc_pos: uint, ns: namespace) -> option<def> {
}
}
}
- mie_class_item(parent_id, class_item) {
- alt class_item.node {
- instance_var(_,_,_,id,_) {
- ret some(ast::def_class_field(local_def(parent_id),
- local_def(id)));
- }
- class_method(it) {
- ret some(ast::def_class_method(local_def(parent_id),
- local_def(it.id)));
- }
- }
- }
}
ret none;
}
node:
item_fn(ctor.node.dec, tps, ctor.node.body),
span: ctor.node.body.span}));
- // add the members
- for ci in items {
- add_to_index(index, class_item_ident(ci),
- mie_class_item(it.id, ci));
- }
}
}
}
ast::def_variant(_, _) { ns_val }
ast::def_fn(_, _) | ast::def_self(_) |
ast::def_const(_) | ast::def_arg(_, _) | ast::def_local(_, _) |
- ast::def_upvar(_, _, _) | ast::def_self(_) |
- ast::def_class_field(_,_) | ast::def_class_method(_,_) { ns_val }
+ ast::def_upvar(_, _, _) | ast::def_self(_) { ns_val }
ast::def_mod(_) | ast::def_native_mod(_) { ns_module }
ast::def_ty(_) | ast::def_binding(_) | ast::def_use(_) |
ast::def_ty_param(_, _) | ast::def_prim_ty(_) | ast::def_class(_)
mie_item(item) { item.span }
mie_enum_variant(_, _, _, span) { span }
mie_native_item(item) { item.span }
- mie_class_item(_,item) { item.span }
};
}
}
}
-// The third argument (path) ends up getting used when the id
-// refers to a field within the enclosing class, since the name
-// gets turned into a record field name.
-fn trans_path(cx: block, id: ast::node_id, path: @ast::path)
+fn trans_path(cx: block, id: ast::node_id)
-> lval_maybe_callee {
let _icx = cx.insn_ctxt("trans_path");
alt cx.tcx().def_map.find(id) {
none { cx.sess().bug("trans_path: unbound node ID"); }
some(df) {
- ret trans_var(cx, df, id, path);
+ ret trans_var(cx, df, id);
}
}
}
-fn trans_var(cx: block, def: ast::def, id: ast::node_id, path: @ast::path)
- -> lval_maybe_callee {
+fn trans_var(cx: block, def: ast::def, id: ast::node_id)-> lval_maybe_callee {
let _icx = cx.insn_ctxt("trans_var");
let ccx = cx.ccx();
alt def {
ret lval_no_env(cx, load_if_immediate(cx, val, tp), owned_imm);
}
}
- ast::def_class_field(parent, did) {
- // base is implicitly "Self"
- alt cx.fcx.llself {
- some(slf) {
- let base = cast_self(cx, slf);
- let {bcx, val, kind} = trans_rec_field_inner(cx, base,
- slf.t,
- path_to_ident(path), path.span);
- ret lval_no_env(bcx, val, kind);
- }
- _ { cx.sess().bug("unbound self param in class"); }
- }
- }
- ast::def_class_method(parent, did) {
- alt cx.fcx.llself {
- some(slf) {
- ret {env: self_env(slf.v, slf.t, none)
- with lval_static_fn(cx, did, id)};
- }
- none { cx.sess().bug("unbound self param in class"); }
- }
- }
_ {
let loc = trans_local_var(cx, def);
ret lval_no_env(cx, loc.val, loc.kind);
fn trans_callee(bcx: block, e: @ast::expr) -> lval_maybe_callee {
let _icx = bcx.insn_ctxt("trans_callee");
alt e.node {
- ast::expr_path(path) { ret trans_path(bcx, e.id, path); }
+ ast::expr_path(path) { ret trans_path(bcx, e.id); }
ast::expr_field(base, ident, _) {
// Lval means this is a record field, so not a method
if !expr_is_lval(bcx, e) {
fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
let _icx = cx.insn_ctxt("trans_lval");
alt e.node {
- ast::expr_path(p) {
- let v = trans_path(cx, e.id, p);
+ ast::expr_path(_) {
+ let v = trans_path(cx, e.id);
ret lval_maybe_callee_to_lval(v, expr_ty(cx, e));
}
ast::expr_field(base, ident, _) {
ast::def_upvar(_, inner, _) {
ret ty_param_bounds_and_ty_for_def(fcx, sp, *inner);
}
- ast::def_class_method(_, id) | ast::def_class_field(_, id) {
- if id.crate != ast::local_crate {
- fcx.ccx.tcx.sess.span_fatal(sp,
- "class method or field referred to \
- out of scope");
- }
- alt fcx.ccx.enclosing_class.find(id.node) {
- some(a_ty) { ret {bounds: @[], ty: a_ty}; }
- _ { fcx.ccx.tcx.sess.span_fatal(sp,
- "class method or field referred to \
- out of scope"); }
- }
- }
-
_ {
// FIXME: handle other names.
fcx.ccx.tcx.sess.unimpl("definition variant");
@def /* closed over def */,
node_id /* expr node that creates the closure */),
def_class(def_id),
- // first def_id is for parent class
- def_class_field(def_id, def_id),
- // No purity allowed for now, I guess
- // (simpler this way, b/c presumably methods read mut state)
- def_class_method(def_id, def_id),
def_region(node_id)
}
def_fn(id, _) | def_mod(id) |
def_native_mod(id) | def_const(id) |
def_variant(_, id) | def_ty(id) | def_ty_param(id, _) |
- def_use(id) |
- def_class(id) | def_class_field(_, id) | def_class_method(_, id) { id }
-
+ def_use(id) | def_class(id) { id }
def_arg(id, _) | def_local(id, _) | def_self(id) |
def_upvar(id, _, _) | def_binding(id) | def_region(id) {
local_def(id)
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
}
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
fn speak() {}
}
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
- fn speak() { meows += 1u; }
- fn meow_count() -> uint { meows }
+ fn speak() { self.meows += 1u; }
+ fn meow_count() -> uint { self.meows }
}
let mut meows : uint;
fn meow() {
#error("Meow");
- meows += 1u;
- if meows % 5u == 0u {
- how_hungry += 1;
+ self.meows += 1u;
+ if self.meows % 5u == 0u {
+ self.how_hungry += 1;
}
}
}
let name : str;
new(in_x : uint, in_y : int, in_name: str)
- { meows = in_x; how_hungry = in_y; name = in_name; }
+ { self.meows = in_x; self.how_hungry = in_y; self.name = in_name; }
- fn speak() { meow(); }
+ fn speak() { self.meow(); }
fn eat() -> bool {
- if how_hungry > 0 {
+ if self.how_hungry > 0 {
#error("OM NOM NOM");
- how_hungry -= 2;
+ self.how_hungry -= 2;
ret true;
}
else {
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
}
\ No newline at end of file
let how_hungry : int;
- fn speak() { meows += 1u; }
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ fn speak() { self.meows += 1u; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
fn main() {
let how_hungry : int;
fn eat() {
- how_hungry -= 5;
+ self.how_hungry -= 5;
}
new(in_x : uint, in_y : int) {
let foo;
- meows = in_x + (in_y as uint);
- how_hungry = foo;
+ self.meows = in_x + (in_y as uint);
+ self.how_hungry = foo;
}
}
-// error-pattern:assigning to immutable class field
+// error-pattern:assigning to immutable field
class cat {
priv {
let mutable meows : uint;
let how_hungry : int;
fn eat() {
- how_hungry -= 5;
+ self.how_hungry -= 5;
}
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
fn main() {
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
fn main() {
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
fn main() {
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
fn main() {
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
- fn speak() { meows += 1u; }
- fn meow_count() -> uint { meows }
+ fn speak() { self.meows += 1u; }
+ fn meow_count() -> uint { self.meows }
}
fn main() {
let name : str;
new(in_name: str)
- { name = in_name; }
+ { self.name = in_name; }
}
fn main() {
let how_hungry : int;
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
fn speak() {}
}
let mut meows : uint;
fn meow() {
#error("Meow");
- meows += 1u;
- if meows % 5u == 0u {
- how_hungry += 1;
+ self.meows += 1u;
+ if self.meows % 5u == 0u {
+ self.how_hungry += 1;
}
}
}
let name : str;
new(in_x : uint, in_y : int, in_name: str)
- { meows = in_x; how_hungry = in_y; name = in_name; }
+ { self.meows = in_x; self.how_hungry = in_y; self.name = in_name; }
- fn speak() { meow(); }
+ fn speak() { self.meow(); }
fn eat() -> bool {
- if how_hungry > 0 {
+ if self.how_hungry > 0 {
#error("OM NOM NOM");
- how_hungry -= 2;
+ self.how_hungry -= 2;
ret true;
}
else {
let how_hungry : int;
- fn meow_count() -> uint { meows }
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ fn meow_count() -> uint { self.meows }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
fn main() {
let how_hungry : int;
fn play() {
- meows += 1u;
+ self.meows += 1u;
self.nap();
}
- new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; }
+ new(in_x : uint, in_y : int) { self.meows = in_x; self.how_hungry = in_y; }
}
fn main() {