Skip to content

Commit 00cdd63

Browse files
committed
auto merge of #15394 : pcwalton/rust/new-index-traits, r=nick29581
This will break code that used the old `Index` trait. Change this code to use the new `Index` traits. For reference, here are their signatures: pub trait Index<Index,Result> { fn index<'a>(&'a self, index: &Index) -> &'a Result; } pub trait IndexMut<Index,Result> { fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result; } Closes #6515. [breaking-change] r? @nick29581
2 parents c175ed4 + 7e4e991 commit 00cdd63

File tree

18 files changed

+433
-167
lines changed

18 files changed

+433
-167
lines changed

src/etc/vim/syntax/rust.vim

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ syn keyword rustTrait Copy Send Sized Share
6565
syn keyword rustTrait Add Sub Mul Div Rem Neg Not
6666
syn keyword rustTrait BitAnd BitOr BitXor
6767
syn keyword rustTrait Drop Deref DerefMut
68-
syn keyword rustTrait Shl Shr Index
68+
syn keyword rustTrait Shl Shr Index IndexMut
6969
syn keyword rustEnum Option
7070
syn keyword rustEnumVariant Some None
7171
syn keyword rustEnum Result

src/libcollections/bitv.rs

+49-15
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,36 @@ use core::cmp;
1616
use core::default::Default;
1717
use core::fmt;
1818
use core::iter::Take;
19-
use core::ops;
2019
use core::slice;
2120
use core::uint;
2221
use std::hash;
2322

2423
use {Collection, Mutable, Set, MutableSet};
2524
use vec::Vec;
2625

26+
#[cfg(not(stage0))]
27+
use core::ops::Index;
28+
29+
#[cfg(not(stage0))]
30+
static TRUE: bool = true;
31+
32+
#[cfg(not(stage0))]
33+
static FALSE: bool = false;
34+
35+
#[deriving(Clone)]
36+
struct SmallBitv {
37+
/// only the lowest nbits of this value are used. the rest is undefined.
38+
bits: uint
39+
}
40+
41+
#[deriving(Clone)]
42+
struct BigBitv {
43+
storage: Vec<uint>
44+
}
45+
46+
#[deriving(Clone)]
47+
enum BitvVariant { Big(BigBitv), Small(SmallBitv) }
48+
2749
/// The bitvector type
2850
///
2951
/// # Example
@@ -58,6 +80,18 @@ pub struct Bitv {
5880
nbits: uint
5981
}
6082

83+
#[cfg(not(stage0))]
84+
impl Index<uint,bool> for Bitv {
85+
#[inline]
86+
fn index<'a>(&'a self, i: &uint) -> &'a bool {
87+
if self.get(*i) {
88+
&TRUE
89+
} else {
90+
&FALSE
91+
}
92+
}
93+
}
94+
6195
struct MaskWords<'a> {
6296
iter: slice::Items<'a, uint>,
6397
next_word: Option<&'a uint>,
@@ -268,7 +302,7 @@ impl Bitv {
268302
if offset >= bitv.nbits {
269303
0
270304
} else {
271-
bitv[offset] as u8 << (7 - bit)
305+
bitv.get(offset) as u8 << (7 - bit)
272306
}
273307
}
274308

@@ -286,6 +320,13 @@ impl Bitv {
286320
)
287321
}
288322

323+
/**
324+
* Transform `self` into a `Vec<bool>` by turning each bit into a `bool`.
325+
*/
326+
pub fn to_bools(&self) -> Vec<bool> {
327+
Vec::from_fn(self.nbits, |i| self.get(i))
328+
}
329+
289330
/**
290331
* Compare a bitvector to a vector of `bool`.
291332
*
@@ -504,13 +545,6 @@ impl Clone for Bitv {
504545
}
505546
}
506547

507-
impl ops::Index<uint,bool> for Bitv {
508-
#[inline]
509-
fn index(&self, i: &uint) -> bool {
510-
self.get(*i)
511-
}
512-
}
513-
514548
impl fmt::Show for Bitv {
515549
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
516550
for bit in self.iter() {
@@ -1369,9 +1403,9 @@ mod tests {
13691403
b2.set(1, true);
13701404
b2.set(2, true);
13711405
assert!(b1.difference(&b2));
1372-
assert!(b1[0]);
1373-
assert!(!b1[1]);
1374-
assert!(!b1[2]);
1406+
assert!(b1.get(0));
1407+
assert!(!b1.get(1));
1408+
assert!(!b1.get(2));
13751409
}
13761410

13771411
#[test]
@@ -1383,9 +1417,9 @@ mod tests {
13831417
b2.set(40, true);
13841418
b2.set(80, true);
13851419
assert!(b1.difference(&b2));
1386-
assert!(b1[0]);
1387-
assert!(!b1[40]);
1388-
assert!(!b1[80]);
1420+
assert!(b1.get(0));
1421+
assert!(!b1.get(40));
1422+
assert!(!b1.get(80));
13891423
}
13901424

13911425
#[test]

src/libcore/ops.rs

+37-4
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
613613
/**
614614
*
615615
* The `Index` trait is used to specify the functionality of indexing operations
616-
* like `arr[idx]`.
616+
* like `arr[idx]` when used in an immutable context.
617617
*
618618
* # Example
619619
*
@@ -624,9 +624,9 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
624624
* struct Foo;
625625
*
626626
* impl Index<Foo, Foo> for Foo {
627-
* fn index(&self, _rhs: &Foo) -> Foo {
627+
* fn index<'a>(&'a self, _rhs: &Foo) -> &'a Foo {
628628
* println!("Indexing!");
629-
* *self
629+
* self
630630
* }
631631
* }
632632
*
@@ -636,9 +636,42 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
636636
* ```
637637
*/
638638
#[lang="index"]
639+
#[cfg(not(stage0))]
639640
pub trait Index<Index,Result> {
640641
/// The method for the indexing (`Foo[Bar]`) operation
641-
fn index(&self, index: &Index) -> Result;
642+
fn index<'a>(&'a self, index: &Index) -> &'a Result;
643+
}
644+
645+
/**
646+
*
647+
* The `IndexMut` trait is used to specify the functionality of indexing
648+
* operations like `arr[idx]`, when used in a mutable context.
649+
*
650+
* # Example
651+
*
652+
* A trivial implementation of `IndexMut`. When `Foo[Foo]` happens, it ends up
653+
* calling `index`, and therefore, `main` prints `Indexing!`.
654+
*
655+
* ```
656+
* struct Foo;
657+
*
658+
* impl IndexMut<Foo, Foo> for Foo {
659+
* fn index_mut<'a>(&'a mut self, _rhs: &Foo) -> &'a mut Foo {
660+
* println!("Indexing!");
661+
* self
662+
* }
663+
* }
664+
*
665+
* fn main() {
666+
* &mut Foo[Foo];
667+
* }
668+
* ```
669+
*/
670+
#[lang="index_mut"]
671+
#[cfg(not(stage0))]
672+
pub trait IndexMut<Index,Result> {
673+
/// The method for the indexing (`Foo[Bar]`) operation
674+
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
642675
}
643676

644677
/**

src/libcore/prelude.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ pub use kinds::{Copy, Send, Sized, Share};
3333
pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
3434
pub use ops::{BitAnd, BitOr, BitXor};
3535
pub use ops::{Drop, Deref, DerefMut};
36-
pub use ops::{Shl, Shr, Index};
36+
pub use ops::{Shl, Shr};
37+
#[cfg(not(stage0))]
38+
pub use ops::{Index, IndexMut};
3739
pub use option::{Option, Some, None};
3840
pub use result::{Result, Ok, Err};
3941

src/librustc/middle/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ lets_do_this! {
234234
ShlTraitLangItem, "shl", shl_trait;
235235
ShrTraitLangItem, "shr", shr_trait;
236236
IndexTraitLangItem, "index", index_trait;
237+
IndexMutTraitLangItem, "index_mut", index_mut_trait;
237238

238239
UnsafeTypeLangItem, "unsafe", unsafe_type;
239240

src/librustc/middle/mem_categorization.rs

+21-13
Original file line numberDiff line numberDiff line change
@@ -443,10 +443,6 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
443443
}
444444

445445
ast::ExprIndex(ref base, _) => {
446-
if self.typer.is_method_call(expr.id) {
447-
return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
448-
}
449-
450446
let base_cmt = if_ok!(self.cat_expr(&**base));
451447
Ok(self.cat_index(expr, base_cmt, 0))
452448
}
@@ -759,7 +755,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
759755

760756
pub fn cat_index<N:ast_node>(&self,
761757
elt: &N,
762-
base_cmt: cmt,
758+
mut base_cmt: cmt,
763759
derefs: uint)
764760
-> cmt {
765761
//! Creates a cmt for an indexing operation (`[]`); this
@@ -793,14 +789,26 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
793789
//! - `derefs`: the deref number to be used for
794790
//! the implicit index deref, if any (see above)
795791
796-
let element_ty = match ty::array_element_ty(base_cmt.ty) {
797-
Some(ref mt) => mt.ty,
798-
None => {
799-
self.tcx().sess.span_bug(
800-
elt.span(),
801-
format!("Explicit index of non-index type `{}`",
802-
base_cmt.ty.repr(self.tcx())).as_slice());
803-
}
792+
let method_call = typeck::MethodCall::expr(elt.id());
793+
let method_ty = self.typer.node_method_ty(method_call);
794+
795+
let element_ty = match method_ty {
796+
Some(method_ty) => {
797+
let ref_ty = ty::ty_fn_ret(method_ty);
798+
base_cmt = self.cat_rvalue_node(elt.id(), elt.span(), ref_ty);
799+
*ty::ty_fn_args(method_ty).get(0)
800+
}
801+
None => {
802+
match ty::array_element_ty(base_cmt.ty) {
803+
Some(ref mt) => mt.ty,
804+
None => {
805+
self.tcx().sess.span_bug(
806+
elt.span(),
807+
format!("Explicit index of non-index type `{}`",
808+
base_cmt.ty.repr(self.tcx())).as_slice());
809+
}
810+
}
811+
}
804812
};
805813

806814
return match deref_kind(self.tcx(), base_cmt.ty) {

0 commit comments

Comments
 (0)