diff options
| -rw-r--r-- | src/libcore/ops.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/astencode.rs | 10 | ||||
| -rw-r--r-- | src/librustc/middle/moves.rs | 28 | ||||
| -rw-r--r-- | src/librustc/middle/trans/expr.rs | 16 | ||||
| -rw-r--r-- | src/librustc/middle/typeck/check/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/bitv.rs | 10 | ||||
| -rw-r--r-- | src/libstd/ebml.rs | 8 | ||||
| -rw-r--r-- | src/test/run-pass/operator-overloading.rs | 4 | ||||
| -rw-r--r-- | src/test/run-pass/overload-index-operator.rs | 55 |
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 |
