Skip to content

Commit 069529b

Browse files
committed
Autoref the argument to the index operator (#4920)
1 parent 2c17ff7 commit 069529b

File tree

9 files changed

+88
-49
lines changed

9 files changed

+88
-49
lines changed

src/libcore/ops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,5 @@ pub trait Shr<RHS,Result> {
7777

7878
#[lang="index"]
7979
pub trait Index<Index,Result> {
80-
fn index(&self, index: Index) -> Result;
80+
fn index(&self, index: &Index) -> Result;
8181
}

src/librustc/middle/astencode.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
342342
}
343343
344344
fn decode_ast(par_doc: ebml::Doc) -> ast::inlined_item {
345-
let chi_doc = par_doc[c::tag_tree as uint];
345+
let chi_doc = par_doc.get(c::tag_tree as uint);
346346
let d = &reader::Decoder(chi_doc);
347347
Decodable::decode(d)
348348
}
@@ -1089,9 +1089,9 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
10891089
fn decode_side_tables(xcx: @ExtendedDecodeContext,
10901090
ast_doc: ebml::Doc) {
10911091
let dcx = xcx.dcx;
1092-
let tbl_doc = ast_doc[c::tag_table as uint];
1092+
let tbl_doc = ast_doc.get(c::tag_table as uint);
10931093
for reader::docs(tbl_doc) |tag, entry_doc| {
1094-
let id0 = entry_doc[c::tag_table_id as uint].as_int();
1094+
let id0 = entry_doc.get(c::tag_table_id as uint).as_int();
10951095
let id = xcx.tr_id(id0);
10961096
10971097
debug!(">> Side table document with tag 0x%x \
@@ -1103,7 +1103,7 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
11031103
} else if tag == (c::tag_table_moves_map as uint) {
11041104
dcx.maps.moves_map.insert(id);
11051105
} else {
1106-
let val_doc = entry_doc[c::tag_table_val as uint];
1106+
let val_doc = entry_doc.get(c::tag_table_val as uint);
11071107
let val_dsr = &reader::Decoder(val_doc);
11081108
if tag == (c::tag_table_def as uint) {
11091109
let def = decode_def(xcx, val_doc);
@@ -1172,7 +1172,7 @@ fn encode_item_ast(ebml_w: writer::Encoder, item: @ast::item) {
11721172
11731173
#[cfg(test)]
11741174
fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item {
1175-
let chi_doc = par_doc[c::tag_tree as uint];
1175+
let chi_doc = par_doc.get(c::tag_tree as uint);
11761176
let d = &reader::Decoder(chi_doc);
11771177
@Decodable::decode(d)
11781178
}

src/librustc/middle/moves.rs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ pub impl VisitContext {
436436

437437
expr_unary(deref, base) => { // *base
438438
if !self.use_overloaded_operator(
439-
expr, DontDerefArgs, base, [], visitor)
439+
expr, base, [], visitor)
440440
{
441441
// Moving out of *base moves out of base.
442442
self.use_expr(base, comp_mode, visitor);
@@ -450,7 +450,7 @@ pub impl VisitContext {
450450

451451
expr_index(lhs, rhs) => { // lhs[rhs]
452452
if !self.use_overloaded_operator(
453-
expr, DontDerefArgs, lhs, [rhs], visitor)
453+
expr, lhs, [rhs], visitor)
454454
{
455455
self.use_expr(lhs, comp_mode, visitor);
456456
self.consume_expr(rhs, visitor);
@@ -579,15 +579,15 @@ pub impl VisitContext {
579579

580580
expr_unary(_, lhs) => {
581581
if !self.use_overloaded_operator(
582-
expr, DontDerefArgs, lhs, [], visitor)
582+
expr, lhs, [], visitor)
583583
{
584584
self.consume_expr(lhs, visitor);
585585
}
586586
}
587587

588588
expr_binary(_, lhs, rhs) => {
589589
if !self.use_overloaded_operator(
590-
expr, DoDerefArgs, lhs, [rhs], visitor)
590+
expr, lhs, [rhs], visitor)
591591
{
592592
self.consume_expr(lhs, visitor);
593593
self.consume_expr(rhs, visitor);
@@ -659,7 +659,6 @@ pub impl VisitContext {
659659

660660
fn use_overloaded_operator(&self,
661661
expr: @expr,
662-
deref_args: DerefArgs,
663662
receiver_expr: @expr,
664663
arg_exprs: &[@expr],
665664
visitor: vt<VisitContext>) -> bool
@@ -670,21 +669,10 @@ pub impl VisitContext {
670669

671670
self.use_receiver(expr.id, expr.span, receiver_expr, visitor);
672671

673-
// The deref_args stuff should eventually be converted into
674-
// adjustments. Moreover, it should eventually be applied
675-
// consistently to all overloaded operators. But that's not
676-
// how it is today.
677-
match deref_args {
678-
DoDerefArgs => {
679-
// we are always passing in a borrowed pointer,
680-
// so it's always read mode:
681-
for arg_exprs.each |arg_expr| {
682-
self.use_expr(*arg_expr, Read, visitor);
683-
}
684-
}
685-
DontDerefArgs => {
686-
self.use_fn_args(expr.callee_id, arg_exprs, visitor);
687-
}
672+
// for overloaded operatrs, we are always passing in a
673+
// borrowed pointer, so it's always read mode:
674+
for arg_exprs.each |arg_expr| {
675+
self.use_expr(*arg_expr, Read, visitor);
688676
}
689677

690678
return true;

src/librustc/middle/trans/expr.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -766,18 +766,15 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
766766
}
767767
ast::expr_binary(_, lhs, rhs) => {
768768
// if not overloaded, would be RvalueDatumExpr
769-
return trans_overloaded_op(bcx, expr, lhs, ~[rhs], dest,
770-
DoAutorefArg);
769+
return trans_overloaded_op(bcx, expr, lhs, ~[rhs], dest);
771770
}
772771
ast::expr_unary(_, subexpr) => {
773772
// if not overloaded, would be RvalueDatumExpr
774-
return trans_overloaded_op(bcx, expr, subexpr, ~[], dest,
775-
DontAutorefArg);
773+
return trans_overloaded_op(bcx, expr, subexpr, ~[], dest);
776774
}
777775
ast::expr_index(base, idx) => {
778776
// if not overloaded, would be RvalueDatumExpr
779-
return trans_overloaded_op(bcx, expr, base, ~[idx], dest,
780-
DontAutorefArg);
777+
return trans_overloaded_op(bcx, expr, base, ~[idx], dest);
781778
}
782779
ast::expr_cast(val, _) => {
783780
match ty::get(node_id_type(bcx, expr.id)).sty {
@@ -1644,16 +1641,15 @@ fn trans_overloaded_op(bcx: block,
16441641
expr: @ast::expr,
16451642
rcvr: @ast::expr,
16461643
+args: ~[@ast::expr],
1647-
dest: Dest,
1648-
+autoref_arg: AutorefArg) -> block
1644+
dest: Dest) -> block
16491645
{
16501646
let origin = *bcx.ccx().maps.method_map.get(&expr.id);
16511647
let fty = node_id_type(bcx, expr.callee_id);
16521648
return callee::trans_call_inner(
16531649
bcx, expr.info(), fty,
16541650
expr_ty(bcx, expr),
16551651
|bcx| meth::trans_method_callee(bcx, expr.callee_id, rcvr, origin),
1656-
callee::ArgExprs(args), dest, autoref_arg);
1652+
callee::ArgExprs(args), dest, DoAutorefArg);
16571653
}
16581654
16591655
fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef,
@@ -1806,7 +1802,7 @@ fn trans_assign_op(bcx: block,
18061802
// FIXME(#2528) evaluates the receiver twice!!
18071803
let scratch = scratch_datum(bcx, dst_datum.ty, false);
18081804
let bcx = trans_overloaded_op(bcx, expr, dst, ~[src],
1809-
SaveIn(scratch.val), DoAutorefArg);
1805+
SaveIn(scratch.val));
18101806
return scratch.move_to_datum(bcx, DROP_EXISTING, dst_datum);
18111807
}
18121808

src/librustc/middle/typeck/check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,7 +1549,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
15491549
lookup_op_method(
15501550
fcx, ex, rhs_expr, rhs_t,
15511551
fcx.tcx().sess.ident_of(mname), ~[],
1552-
DontDerefArgs, DontAutoderefReceiver,
1552+
DoDerefArgs, DontAutoderefReceiver,
15531553
|| {
15541554
fcx.type_error_message(ex.span, |actual| {
15551555
fmt!("cannot apply unary operator `%s` to type `%s`",
@@ -2757,7 +2757,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
27572757
expr.span, raw_base_t);
27582758
let ret_ty = lookup_op_method(fcx, expr, base, resolved,
27592759
tcx.sess.ident_of(~"index"),
2760-
~[idx], DontDerefArgs, AutoderefReceiver,
2760+
~[idx], DoDerefArgs, AutoderefReceiver,
27612761
|| {
27622762
fcx.type_error_message(expr.span, |actual|
27632763
fmt!("cannot index a value \

src/libstd/bitv.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,8 @@ pub impl Bitv {
437437
if offset >= bitv.nbits {
438438
0
439439
} else {
440-
bitv[offset] as u8 << (7 - bit)
440+
// NOTE cannot use bitv[offset] until snapshot
441+
bitv.index(&offset) as u8 << (7 - bit)
441442
}
442443
}
443444
@@ -459,7 +460,8 @@ pub impl Bitv {
459460
* Transform self into a [bool] by turning each bit into a bool
460461
*/
461462
fn to_bools(&self) -> ~[bool] {
462-
vec::from_fn(self.nbits, |i| self[i])
463+
// NOTE cannot use self[i] until snapshot
464+
vec::from_fn(self.nbits, |i| self.index(&i))
463465
}
464466
465467
/**
@@ -555,8 +557,8 @@ pub fn from_fn(len: uint, f: &fn(index: uint) -> bool) -> Bitv {
555557
}
556558
557559
impl ops::Index<uint,bool> for Bitv {
558-
fn index(&self, i: uint) -> bool {
559-
self.get(i)
560+
fn index(&self, i: &uint) -> bool {
561+
self.get(*i)
560562
}
561563
}
562564

src/libstd/ebml.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,9 @@ pub mod reader {
6868

6969
// ebml reading
7070

71-
impl ops::Index<uint,Doc> for Doc {
72-
fn index(&self, tag: uint) -> Doc {
73-
unsafe {
74-
get_doc(*self, tag)
75-
}
71+
pub impl Doc {
72+
fn get(&self, tag: uint) -> Doc {
73+
get_doc(*self, tag)
7674
}
7775
}
7876

src/test/run-pass/operator-overloading.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ impl ops::Not<Point> for Point {
4040
}
4141

4242
impl ops::Index<bool,int> for Point {
43-
fn index(&self, +x: bool) -> int {
44-
if x { self.x } else { self.y }
43+
fn index(&self, +x: &bool) -> int {
44+
if *x { self.x } else { self.y }
4545
}
4646
}
4747

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test overloading of the `[]` operator. In particular test that it
12+
// takes its argument *by reference*.
13+
14+
use core::ops::Index;
15+
16+
struct AssociationList<K,V> {
17+
pairs: ~[AssociationPair<K,V>]
18+
}
19+
20+
struct AssociationPair<K,V> {
21+
key: K,
22+
value: V
23+
}
24+
25+
impl<K,V> AssociationList<K,V> {
26+
fn push(&mut self, key: K, value: V) {
27+
self.pairs.push(AssociationPair {key: key, value: value});
28+
}
29+
}
30+
31+
impl<K:Eq,V:Copy> Index<K,V> for AssociationList<K,V> {
32+
fn index(&self, index: &K) -> V {
33+
for self.pairs.each |pair| {
34+
if pair.key == *index {
35+
return copy pair.value;
36+
}
37+
}
38+
fail!(fmt!("No value found for key: %?", index));
39+
}
40+
}
41+
42+
pub fn main() {
43+
let foo = ~"foo";
44+
let bar = ~"bar";
45+
46+
let mut list = AssociationList {pairs: ~[]};
47+
list.push(copy foo, 22);
48+
list.push(copy bar, 44);
49+
50+
fail_unless!(list[foo] == 22)
51+
fail_unless!(list[bar] == 44)
52+
53+
fail_unless!(list[foo] == 22)
54+
fail_unless!(list[bar] == 44)
55+
}

0 commit comments

Comments
 (0)