]> git.lizzy.rs Git - rust.git/commitdiff
Require "self" as base expression for intra-class method or field references
authorTim Chevalier <chevalier@alum.wellesley.edu>
Thu, 29 Mar 2012 19:21:13 +0000 (12:21 -0700)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Thu, 29 Mar 2012 19:22:01 +0000 (12:22 -0700)
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.

24 files changed:
src/rustc/metadata/astencode.rs
src/rustc/middle/mutbl.rs
src/rustc/middle/resolve.rs
src/rustc/middle/trans/base.rs
src/rustc/middle/typeck.rs
src/rustc/syntax/ast.rs
src/rustc/syntax/ast_util.rs
src/test/auxiliary/cci_class.rs
src/test/auxiliary/cci_class_2.rs
src/test/auxiliary/cci_class_3.rs
src/test/auxiliary/cci_class_4.rs
src/test/auxiliary/cci_class_5.rs
src/test/compile-fail/assign-to-method.rs
src/test/compile-fail/ctor-uninit-var.rs
src/test/compile-fail/mutable-class-fields-2.rs
src/test/compile-fail/mutable-class-fields.rs
src/test/compile-fail/private-class-field.rs
src/test/compile-fail/private-method.rs
src/test/run-pass/class-methods.rs
src/test/run-pass/class-str-field.rs
src/test/run-pass/classes-simple-method.rs
src/test/run-pass/classes.rs
src/test/run-pass/private-class-field.rs
src/test/run-pass/private-method.rs

index fab2c48dda93296e0e917c0a44c78da3a312a82d..5d7802e08c0fbc19aff6f4b3fd41e67b0fb2daa6 100644 (file)
@@ -443,12 +443,6 @@ fn tr(xcx: extended_decode_ctxt) -> ast::def {
           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)) }
         }
     }
index 45751bd4cfbf1a29b33922a20006eea54f0783e7..268d63b84f52f30a8d3d504de41fc5ec7a194caf 100644 (file)
@@ -321,7 +321,7 @@ fn check_bind(cx: @ctx, f: @expr, args: [option<@expr>]) {
 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) {
@@ -354,18 +354,6 @@ fn is_illegal_to_modify_def(cx: @ctx, def: def, msg: msg) -> option<str> {
       }
 
       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 }
     }
 }
index 7f38205b3843cec4a6a8361b7d9b96416a7c289e..3fe98999cefad7967d2a5f33e830c7e1d3bb417d 100644 (file)
@@ -88,8 +88,6 @@ enum mod_index_entry {
     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],
@@ -1017,9 +1015,6 @@ fn in_scope(e: env, sp: span, name: ident, s: scope, ns: namespace) ->
                       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
               }
@@ -1156,30 +1151,6 @@ fn lookup_in_fn(e: env, name: ident, decl: ast::fn_decl,
     }
 }
 
-/*
-   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> {
 
@@ -1559,18 +1530,6 @@ fn lookup_in_mie(e: env, mie: mod_index_entry, ns: namespace) ->
           }
         }
       }
-      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;
 }
@@ -1648,11 +1607,6 @@ fn index_mod(md: ast::_mod) -> mod_index {
                             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));
-              }
           }
         }
     }
@@ -1678,8 +1632,7 @@ fn ns_for_def(d: def) -> namespace {
       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(_)
@@ -1761,7 +1714,6 @@ fn mie_span(mie: mod_index_entry) -> span {
           mie_item(item) { item.span }
           mie_enum_variant(_, _, _, span) { span }
           mie_native_item(item) { item.span }
-          mie_class_item(_,item) { item.span }
         };
 }
 
index f213519dac3bc3689b5f73211ea3eee91755d71e..26565b05b97e96b97163afc79d2fbc316e575c95 100644 (file)
@@ -2177,22 +2177,18 @@ fn take_local(table: hashmap<ast::node_id, local_val>,
     }
 }
 
-// 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 {
@@ -2225,28 +2221,6 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id, path: @ast::path)
             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);
@@ -2323,7 +2297,7 @@ fn expr_is_lval(bcx: block, e: @ast::expr) -> bool {
 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) {
@@ -2350,8 +2324,8 @@ fn trans_callee(bcx: block, e: @ast::expr) -> lval_maybe_callee {
 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, _) {
index 1cf89045a709a132743430f452d915892bf75c52..5fde3ab75de9e121da446fd8e39f1affc18cfb68 100644 (file)
@@ -170,20 +170,6 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
       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");
index c88f44d7153463ec233e7721116b25172daec4f0..c6fe959e2902d44308ed97504848fc946c25a5da 100644 (file)
@@ -83,11 +83,6 @@ enum def {
               @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)
 }
 
index bf32bb0ebf38fcaa9af35811916902165339dfcc..5e0f1c898179bd53932948bd0319a92ef5a0e0dd 100644 (file)
@@ -40,9 +40,7 @@ fn def_id_of_def(d: def) -> def_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)
index cda361c1be970ae4fcef426a485fc58ef223cef2..182bfd351d481910544e545bbea1f6c73c43c5c7 100644 (file)
@@ -7,7 +7,7 @@ mod kitties {
 
   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; }
 }
 
 }
index 0bb398839d165c4ef0a1a74c93a196dbbf519785..92ffb217f6af2afcfff13e9df0c487adc8d20562 100644 (file)
@@ -7,7 +7,7 @@ mod kitties {
 
   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() {}
 }
index a30233c8135b8e565a80f038fe3374e4451366ce..dab856377f8f38831c06a14fe2d7ff49a7184b02 100644 (file)
@@ -7,10 +7,10 @@ mod kitties {
 
   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 }
 
 }
 
index e44a90e5a5c521b2d7558409325c33d42b4772f6..1ed65b21d036be33a2b3c613da788afef2747026 100644 (file)
@@ -5,9 +5,9 @@ mod kitties {
     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;
       }
     }
   }
@@ -16,14 +16,14 @@ fn meow() {
   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 {
index 6dc4d76cf5248a15e1648d6b68d82eb6628a8dd7..dc9339370583f25e0796af430ade4808087baa5f 100644 (file)
@@ -8,7 +8,7 @@ fn nap() { uint::range(1u, 10000u) {|_i|}}
 
   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
index aea25979d9b2b91de042f2c4a065b24d42d59876..bec203900675805a73e9df7858412f483353bf27 100644 (file)
@@ -6,8 +6,8 @@
 
   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() {
index b2af5e48f0133a97f61f012c2ab41bfe56dd7576..5450cd771895de57afcc1a488dd03df3235e501e 100644 (file)
@@ -7,13 +7,13 @@
   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;
   }
 }
 
index edfb5a920582ada1211ad0b89455d89c815f0a94..1c06727ec2e6545234c6c32c305591cee7c9c19c 100644 (file)
@@ -1,4 +1,4 @@
-// error-pattern:assigning to immutable class field
+// error-pattern:assigning to immutable field
 class cat {
   priv {
     let mutable meows : uint;
@@ -7,10 +7,10 @@
   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() {
index b345c0c80f1d44f588f03f8615dcaf33b55063a4..adac61c5e64e1f352b2cd78f0e51b3cc42fa417c 100644 (file)
@@ -6,7 +6,7 @@
 
   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() {
index c0fb997d14c0bb89afbfbe7990ca74d75ba8d45d..15aba5d009d070c7becd0d4535cad0c4b51935a2 100644 (file)
@@ -6,7 +6,7 @@
 
   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() {
index 09f0f9b5af5b5ec950441586cb2e649948bb0c2f..b6a16c33a2bc4aa917e7c1bbf9045d09a2f249c5 100644 (file)
@@ -7,7 +7,7 @@ fn nap() { uint::range(1u, 10000u) {|_i|}}
 
   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() {
index f1769b0fb5039c15c3e8bd62fec952f23b46a01d..8023879ca9711ed73755e046133578ab30e56215 100644 (file)
@@ -5,10 +5,10 @@
 
   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() {
index 831006a7dfd76f54bc0b32e609aec156614b7aba..fab99f2591085a551865188fcb8207345a9f2d86 100644 (file)
@@ -3,7 +3,7 @@
   let name : str;
 
   new(in_name: str)
-    { name = in_name; }
+    { self.name = in_name; }
 }
 
 fn main() {
index dff5a035d987d6934c0cee600166b731dc5d5207..8fcf5b96be2d82f113b9f985c61f9e29cc4a177d 100644 (file)
@@ -5,7 +5,7 @@
 
   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() {}
 }
index 32add1b606d52c8ad566a5f5475b44a7aa8bab10..f2790cee35480022c14002807e5c646bbc64db18 100644 (file)
@@ -3,9 +3,9 @@
     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;
       }
     }
   }
@@ -14,14 +14,14 @@ fn meow() {
   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 {
index f2f7c795252b2cd2f216b9738caedc0050101d52..a6baea1ffa7d376896c2db617bf63f6cc34b38ed 100644 (file)
@@ -5,8 +5,8 @@
 
   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() {
index 1d062f32b7a19e1e2b2320fa680214a884a9d552..fab6bbaf7d985656a3f70d7fb6fe55e42fd09f8d 100644 (file)
@@ -7,10 +7,10 @@ fn nap() { uint::range(1u, 10u) {|_i|}}
   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() {