about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/ops.rs2
-rw-r--r--src/librustc/middle/astencode.rs10
-rw-r--r--src/librustc/middle/moves.rs28
-rw-r--r--src/librustc/middle/trans/expr.rs16
-rw-r--r--src/librustc/middle/typeck/check/mod.rs4
-rw-r--r--src/libstd/bitv.rs10
-rw-r--r--src/libstd/ebml.rs8
-rw-r--r--src/test/run-pass/operator-overloading.rs4
-rw-r--r--src/test/run-pass/overload-index-operator.rs55
9 files changed, 88 insertions, 49 deletions
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 2f7fe1e4aa8..d0623ef6040 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -77,5 +77,5 @@ pub trait Shr<RHS,Result> {
 
 #[lang="index"]
 pub trait Index<Index,Result> {
-    fn index(&self, index: Index) -> Result;
+    fn index(&self, index: &Index) -> Result;
 }
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 1e1dde33037..2ec5b59b9c5 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -342,7 +342,7 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
 }
 
 fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item {
-    let chi_doc = par_doc[c::tag_tree as uint];
+    let chi_doc = par_doc.get(c::tag_tree as uint);
     let d = &reader::Decoder(chi_doc);
     Decodable::decode(d)
 }
@@ -1089,9 +1089,9 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
 fn decode_side_tables(xcx: @ExtendedDecodeContext,
                       ast_doc: ebml::Doc) {
     let dcx = xcx.dcx;
-    let tbl_doc = ast_doc[c::tag_table as uint];
+    let tbl_doc = ast_doc.get(c::tag_table as uint);
     for reader::docs(tbl_doc) |tag, entry_doc| {
-        let id0 = entry_doc[c::tag_table_id as uint].as_int();
+        let id0 = entry_doc.get(c::tag_table_id as uint).as_int();
         let id = xcx.tr_id(id0);
 
         debug!(">> Side table document with tag 0x%x \
@@ -1103,7 +1103,7 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
         } else if tag == (c::tag_table_moves_map as uint) {
             dcx.maps.moves_map.insert(id);
         } else {
-            let val_doc = entry_doc[c::tag_table_val as uint];
+            let val_doc = entry_doc.get(c::tag_table_val as uint);
             let val_dsr = &reader::Decoder(val_doc);
             if tag == (c::tag_table_def as uint) {
                 let def = decode_def(xcx, val_doc);
@@ -1172,7 +1172,7 @@ fn encode_item_ast(ebml_w: writer::Encoder, item: @ast::item) {
 
 #[cfg(test)]
 fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item {
-    let chi_doc = par_doc[c::tag_tree as uint];
+    let chi_doc = par_doc.get(c::tag_tree as uint);
     let d = &reader::Decoder(chi_doc);
     @Decodable::decode(d)
 }
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index d97ec6b9905..f5382d69174 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -436,7 +436,7 @@ pub impl VisitContext {
 
             expr_unary(deref, base) => {       // *base
                 if !self.use_overloaded_operator(
-                    expr, DontDerefArgs, base, [], visitor)
+                    expr, base, [], visitor)
                 {
                     // Moving out of *base moves out of base.
                     self.use_expr(base, comp_mode, visitor);
@@ -450,7 +450,7 @@ pub impl VisitContext {
 
             expr_index(lhs, rhs) => {          // lhs[rhs]
                 if !self.use_overloaded_operator(
-                    expr, DontDerefArgs, lhs, [rhs], visitor)
+                    expr, lhs, [rhs], visitor)
                 {
                     self.use_expr(lhs, comp_mode, visitor);
                     self.consume_expr(rhs, visitor);
@@ -579,7 +579,7 @@ pub impl VisitContext {
 
             expr_unary(_, lhs) => {
                 if !self.use_overloaded_operator(
-                    expr, DontDerefArgs, lhs, [], visitor)
+                    expr, lhs, [], visitor)
                 {
                     self.consume_expr(lhs, visitor);
                 }
@@ -587,7 +587,7 @@ pub impl VisitContext {
 
             expr_binary(_, lhs, rhs) => {
                 if !self.use_overloaded_operator(
-                    expr, DoDerefArgs, lhs, [rhs], visitor)
+                    expr, lhs, [rhs], visitor)
                 {
                     self.consume_expr(lhs, visitor);
                     self.consume_expr(rhs, visitor);
@@ -659,7 +659,6 @@ pub impl VisitContext {
 
     fn use_overloaded_operator(&self,
                                expr: @expr,
-                               deref_args: DerefArgs,
                                receiver_expr: @expr,
                                arg_exprs: &[@expr],
                                visitor: vt<VisitContext>) -> bool
@@ -670,21 +669,10 @@ pub impl VisitContext {
 
         self.use_receiver(expr.id, expr.span, receiver_expr, visitor);
 
-        // The deref_args stuff should eventually be converted into
-        // adjustments.  Moreover, it should eventually be applied
-        // consistently to all overloaded operators.  But that's not
-        // how it is today.
-        match deref_args {
-            DoDerefArgs => {
-                // we are always passing in a borrowed pointer,
-                // so it's always read mode:
-                for arg_exprs.each |arg_expr| {
-                    self.use_expr(*arg_expr, Read, visitor);
-                }
-            }
-            DontDerefArgs => {
-                self.use_fn_args(expr.callee_id, arg_exprs, visitor);
-            }
+        // for overloaded operatrs, we are always passing in a
+        // borrowed pointer, so it's always read mode:
+        for arg_exprs.each |arg_expr| {
+            self.use_expr(*arg_expr, Read, visitor);
         }
 
         return true;
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 33576a682a7..0da1a9acef2 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -766,18 +766,15 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
         }
         ast::expr_binary(_, lhs, rhs) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx, expr, lhs, ~[rhs], dest,
-                                       DoAutorefArg);
+            return trans_overloaded_op(bcx, expr, lhs, ~[rhs], dest);
         }
         ast::expr_unary(_, subexpr) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx, expr, subexpr, ~[], dest,
-                                       DontAutorefArg);
+            return trans_overloaded_op(bcx, expr, subexpr, ~[], dest);
         }
         ast::expr_index(base, idx) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx, expr, base, ~[idx], dest,
-                                       DontAutorefArg);
+            return trans_overloaded_op(bcx, expr, base, ~[idx], dest);
         }
         ast::expr_cast(val, _) => {
             match ty::get(node_id_type(bcx, expr.id)).sty {
@@ -1644,8 +1641,7 @@ fn trans_overloaded_op(bcx: block,
                        expr: @ast::expr,
                        rcvr: @ast::expr,
                        +args: ~[@ast::expr],
-                       dest: Dest,
-                       +autoref_arg: AutorefArg) -> block
+                       dest: Dest) -> block
 {
     let origin = *bcx.ccx().maps.method_map.get(&expr.id);
     let fty = node_id_type(bcx, expr.callee_id);
@@ -1653,7 +1649,7 @@ fn trans_overloaded_op(bcx: block,
         bcx, expr.info(), fty,
         expr_ty(bcx, expr),
         |bcx| meth::trans_method_callee(bcx, expr.callee_id, rcvr, origin),
-        callee::ArgExprs(args), dest, autoref_arg);
+        callee::ArgExprs(args), dest, DoAutorefArg);
 }
 
 fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
@@ -1806,7 +1802,7 @@ fn trans_assign_op(bcx: block,
         // FIXME(#2528) evaluates the receiver twice!!
         let scratch = scratch_datum(bcx, dst_datum.ty, false);
         let bcx = trans_overloaded_op(bcx, expr, dst, ~[src],
-                                      SaveIn(scratch.val), DoAutorefArg);
+                                      SaveIn(scratch.val));
         return scratch.move_to_datum(bcx, DROP_EXISTING, dst_datum);
     }
 
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index d568773f90f..732026a3033 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1549,7 +1549,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
        lookup_op_method(
             fcx, ex, rhs_expr, rhs_t,
             fcx.tcx().sess.ident_of(mname), ~[],
-            DontDerefArgs, DontAutoderefReceiver,
+            DoDerefArgs, DontAutoderefReceiver,
             || {
                 fcx.type_error_message(ex.span, |actual| {
                     fmt!("cannot apply unary operator `%s` to type `%s`",
@@ -2757,7 +2757,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                           expr.span, raw_base_t);
                       let ret_ty = lookup_op_method(fcx, expr, base, resolved,
                                              tcx.sess.ident_of(~"index"),
-                                             ~[idx], DontDerefArgs, AutoderefReceiver,
+                                             ~[idx], DoDerefArgs, AutoderefReceiver,
                         || {
                             fcx.type_error_message(expr.span, |actual|
                                 fmt!("cannot index a value \
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs
index 3acc95a3aad..8bac0fed3c9 100644
--- a/src/libstd/bitv.rs
+++ b/src/libstd/bitv.rs
@@ -437,7 +437,8 @@ pub impl Bitv {
             if offset >= bitv.nbits {
                 0
             } else {
-                bitv[offset] as u8 << (7 - bit)
+                // NOTE cannot use bitv[offset] until snapshot
+                bitv.index(&offset) as u8 << (7 - bit)
             }
         }
 
@@ -459,7 +460,8 @@ pub impl Bitv {
      * Transform self into a [bool] by turning each bit into a bool
      */
     fn to_bools(&self) -> ~[bool] {
-        vec::from_fn(self.nbits, |i| self[i])
+        // NOTE cannot use self[i] until snapshot
+        vec::from_fn(self.nbits, |i| self.index(&i))
     }
 
     /**
@@ -555,8 +557,8 @@ pub fn from_fn(len: uint, f: &fn(index: uint) -> bool) -> Bitv {
 }
 
 impl ops::Index<uint,bool> for Bitv {
-    fn index(&self, i: uint) -> bool {
-        self.get(i)
+    fn index(&self, i: &uint) -> bool {
+        self.get(*i)
     }
 }
 
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index 92898af2993..b82616d386a 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -68,11 +68,9 @@ pub mod reader {
 
     // ebml reading
 
-    impl ops::Index<uint,Doc> for Doc {
-        fn index(&self, tag: uint) -> Doc {
-            unsafe {
-                get_doc(*self, tag)
-            }
+    pub impl Doc {
+        fn get(&self, tag: uint) -> Doc {
+            get_doc(*self, tag)
         }
     }
 
diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs
index 9299e3e365e..6f479140d73 100644
--- a/src/test/run-pass/operator-overloading.rs
+++ b/src/test/run-pass/operator-overloading.rs
@@ -40,8 +40,8 @@ impl ops::Not<Point> for Point {
 }
 
 impl ops::Index<bool,int> for Point {
-    fn index(&self, +x: bool) -> int {
-        if x { self.x } else { self.y }
+    fn index(&self, +x: &bool) -> int {
+        if *x { self.x } else { self.y }
     }
 }
 
diff --git a/src/test/run-pass/overload-index-operator.rs b/src/test/run-pass/overload-index-operator.rs
new file mode 100644
index 00000000000..7d1d0c6be0e
--- /dev/null
+++ b/src/test/run-pass/overload-index-operator.rs
@@ -0,0 +1,55 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test overloading of the `[]` operator.  In particular test that it
+// takes its argument *by reference*.
+
+use core::ops::Index;
+
+struct AssociationList<K,V> {
+    pairs: ~[AssociationPair<K,V>]
+}
+
+struct AssociationPair<K,V> {
+    key: K,
+    value: V
+}
+
+impl<K,V> AssociationList<K,V> {
+    fn push(&mut self, key: K, value: V) {
+        self.pairs.push(AssociationPair {key: key, value: value});
+    }
+}
+
+impl<K:Eq,V:Copy> Index<K,V> for AssociationList<K,V> {
+    fn index(&self, index: &K) -> V {
+        for self.pairs.each |pair| {
+            if pair.key == *index {
+                return copy pair.value;
+            }
+        }
+        fail!(fmt!("No value found for key: %?", index));
+    }
+}
+
+pub fn main() {
+    let foo = ~"foo";
+    let bar = ~"bar";
+
+    let mut list = AssociationList {pairs: ~[]};
+    list.push(copy foo, 22);
+    list.push(copy bar, 44);
+
+    fail_unless!(list[foo] == 22)
+    fail_unless!(list[bar] == 44)
+
+    fail_unless!(list[foo] == 22)
+    fail_unless!(list[bar] == 44)
+}
\ No newline at end of file