From aae14e352af95ad70d862e0e952d3817fc6c9c27 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Fri, 23 Mar 2012 23:08:41 -0700 Subject: [PATCH] Allow methods to call other methods in the same class --- src/rustc/middle/trans/base.rs | 17 ++++++++++-- src/test/auxiliary/cci_class_4.rs | 34 ++++++++++++++++++++++++ src/test/run-pass/classes-cross-crate.rs | 12 +++++++++ src/test/run-pass/classes.rs | 17 +++++++++--- 4 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 src/test/auxiliary/cci_class_4.rs create mode 100644 src/test/run-pass/classes-cross-crate.rs diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 6be5db508f9..f9f1cedb32c 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2241,7 +2241,16 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id, path: @ast::path) } _ { 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); @@ -2266,7 +2275,11 @@ fn trans_rec_field_inner(bcx: block, val: ValueRef, ty: ty::t, _ { bcx.tcx().sess.span_bug(sp, "trans_rec_field:\ base expr has non-record type"); } }; - let ix = option::get(ty::field_idx(field, fields)); + let ix = alt ty::field_idx(field, fields) { + none { bcx.tcx().sess.span_bug(sp, #fmt("trans_rec_field:\ + base expr doesn't appear to have a field named %s", field));} + some(i) { i } + }; let val = GEPi(bcx, val, [0, ix as int]); ret {bcx: bcx, val: val, kind: owned}; } diff --git a/src/test/auxiliary/cci_class_4.rs b/src/test/auxiliary/cci_class_4.rs new file mode 100644 index 00000000000..838157ac010 --- /dev/null +++ b/src/test/auxiliary/cci_class_4.rs @@ -0,0 +1,34 @@ +mod kitties { + +class cat { + priv { + let mutable meows : uint; + fn meow() { + #error("Meow"); + meows += 1u; + if meows % 5u == 0u { + how_hungry += 1; + } + } + } + + let how_hungry : int; + + new(in_x : uint, in_y : int) { meows = in_x; how_hungry = in_y; } + + fn speak() { meow(); } + + fn eat() -> bool { + if how_hungry > 0 { + #error("OM NOM NOM"); + how_hungry -= 2; + ret true; + } + else { + #error("Not hungry!"); + ret false; + } + } +} + +} diff --git a/src/test/run-pass/classes-cross-crate.rs b/src/test/run-pass/classes-cross-crate.rs new file mode 100644 index 00000000000..b4f46c51305 --- /dev/null +++ b/src/test/run-pass/classes-cross-crate.rs @@ -0,0 +1,12 @@ +// xfail-fast +// aux-build:cci_class_4.rs +use cci_class_4; +import cci_class_4::kitties::*; + +fn main() { + let nyan = cat(0u, 2); + nyan.eat(); + assert(!nyan.eat()); + uint::range(1u, 10u, {|_i| nyan.speak(); }); + assert(nyan.eat()); +} \ No newline at end of file diff --git a/src/test/run-pass/classes.rs b/src/test/run-pass/classes.rs index 2d67bc26785..c2d5735969c 100644 --- a/src/test/run-pass/classes.rs +++ b/src/test/run-pass/classes.rs @@ -1,11 +1,10 @@ -// xfail-test class cat { priv { let mutable meows : uint; fn meow() { #error("Meow"); - meows += 1; - if meows % 5 == 0 { + meows += 1u; + if meows % 5u == 0u { how_hungry += 1; } } @@ -17,13 +16,23 @@ class cat { fn speak() { meow(); } - fn eat() { + fn eat() -> bool { if how_hungry > 0 { #error("OM NOM NOM"); how_hungry -= 2; + ret true; } else { #error("Not hungry!"); + ret false; } } +} + +fn main() { + let nyan = cat(0u, 2); + nyan.eat(); + assert(!nyan.eat()); + uint::range(1u, 10u, {|_i| nyan.speak(); }); + assert(nyan.eat()); } \ No newline at end of file