Skip to content

Use associated types in Index[Mut] #20486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/libcollections/bit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ pub struct Bitv {
nbits: uint
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
// FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing)
impl Index<uint,bool> for Bitv {
#[inline]
Expand All @@ -176,6 +178,21 @@ impl Index<uint,bool> for Bitv {
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
// FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing)
impl Index<uint> for Bitv {
type Output = bool;

#[inline]
fn index(&self, i: &uint) -> &bool {
if self.get(*i).expect("index out of bounds") {
&TRUE
} else {
&FALSE
}
}
}

/// Computes how many blocks are needed to store that many bits
fn blocks_for_bits(bits: uint) -> uint {
// If we want 17 bits, dividing by 32 will produce 0. So we add 1 to make sure we
Expand Down
28 changes: 28 additions & 0 deletions src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,8 @@ impl<K: Show, V: Show> Show for BTreeMap<K, V> {
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<K: Ord, Sized? Q, V> Index<Q, V> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
Expand All @@ -907,6 +909,20 @@ impl<K: Ord, Sized? Q, V> Index<Q, V> for BTreeMap<K, V>
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<K: Ord, Sized? Q, V> Index<Q> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
{
type Output = V;

fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<K: Ord, Sized? Q, V> IndexMut<Q, V> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
Expand All @@ -916,6 +932,18 @@ impl<K: Ord, Sized? Q, V> IndexMut<Q, V> for BTreeMap<K, V>
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<K: Ord, Sized? Q, V> IndexMut<Q> for BTreeMap<K, V>
where Q: BorrowFrom<K> + Ord
{
type Output = V;

fn index_mut(&mut self, key: &Q) -> &mut V {
self.get_mut(key).expect("no entry found for key")
}
}

/// Genericises over how to get the correct type of iterator from the correct type
/// of Node ownership.
trait Traverse<N> {
Expand Down
26 changes: 26 additions & 0 deletions src/libcollections/ring_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,8 @@ impl<S: Writer, A: Hash<S>> Hash<S> for RingBuf<A> {
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<A> Index<uint, A> for RingBuf<A> {
#[inline]
Expand All @@ -1372,6 +1374,19 @@ impl<A> Index<uint, A> for RingBuf<A> {
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<A> Index<uint> for RingBuf<A> {
type Output = A;

#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a A {
self.get(*i).expect("Out of bounds access")
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<A> IndexMut<uint, A> for RingBuf<A> {
#[inline]
Expand All @@ -1380,6 +1395,17 @@ impl<A> IndexMut<uint, A> for RingBuf<A> {
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<A> IndexMut<uint> for RingBuf<A> {
type Output = A;

#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut A {
self.get_mut(*i).expect("Out of bounds access")
}
}

#[stable]
impl<A> FromIterator<A> for RingBuf<A> {
fn from_iter<T: Iterator<A>>(iterator: T) -> RingBuf<A> {
Expand Down
25 changes: 25 additions & 0 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,8 @@ impl<S: hash::Writer, T: Hash<S>> Hash<S> for Vec<T> {
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[experimental = "waiting on Index stability"]
impl<T> Index<uint,T> for Vec<T> {
#[inline]
Expand All @@ -1253,13 +1255,36 @@ impl<T> Index<uint,T> for Vec<T> {
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[experimental = "waiting on Index stability"]
impl<T> Index<uint> for Vec<T> {
type Output = T;

#[inline]
fn index<'a>(&'a self, index: &uint) -> &'a T {
&self.as_slice()[*index]
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
impl<T> IndexMut<uint,T> for Vec<T> {
#[inline]
fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T {
&mut self.as_mut_slice()[*index]
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<T> IndexMut<uint> for Vec<T> {
type Output = T;

#[inline]
fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T {
&mut self.as_mut_slice()[*index]
}
}

impl<T> ops::Slice<uint, [T]> for Vec<T> {
#[inline]
fn as_slice_<'a>(&'a self) -> &'a [T] {
Expand Down
25 changes: 25 additions & 0 deletions src/libcollections/vec_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ impl<V> Extend<(uint, V)> for VecMap<V> {
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<V> Index<uint, V> for VecMap<V> {
#[inline]
Expand All @@ -570,6 +572,18 @@ impl<V> Index<uint, V> for VecMap<V> {
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
impl<V> Index<uint> for VecMap<V> {
type Output = V;

#[inline]
fn index<'a>(&'a self, i: &uint) -> &'a V {
self.get(i).expect("key not present")
}
}

// NOTE(stage0): remove impl after a snapshot
#[cfg(stage0)]
#[stable]
impl<V> IndexMut<uint, V> for VecMap<V> {
#[inline]
Expand All @@ -578,6 +592,17 @@ impl<V> IndexMut<uint, V> for VecMap<V> {
}
}

#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot
#[stable]
impl<V> IndexMut<uint> for VecMap<V> {
type Output = V;

#[inline]
fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut V {
self.get_mut(i).expect("key not present")
}
}

macro_rules! iterator {
(impl $name:ident -> $elem:ty, $($getter:ident),+) => {
#[stable]
Expand Down
44 changes: 38 additions & 6 deletions src/libcore/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,15 @@ macro_rules! shr_impl {

shr_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }

// NOTE(stage0) remove trait after a snapshot
#[cfg(stage0)]
#[allow(missing_docs)]
#[lang="index"]
pub trait Index<Sized? Index, Sized? Result> for Sized? {
/// The method for the indexing (`Foo[Bar]`) operation
fn index<'a>(&'a self, index: &Index) -> &'a Result;
}

/// The `Index` trait is used to specify the functionality of indexing operations
/// like `arr[idx]` when used in an immutable context.
///
Expand All @@ -620,12 +629,16 @@ shr_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
/// calling `index`, and therefore, `main` prints `Indexing!`.
///
/// ```
/// #![feature(associated_types)]
///
/// use std::ops::Index;
///
/// #[deriving(Copy)]
/// struct Foo;
///
/// impl Index<Foo, Foo> for Foo {
/// impl Index<Foo> for Foo {
/// type Output = Foo;
///
/// fn index<'a>(&'a self, _index: &Foo) -> &'a Foo {
/// println!("Indexing!");
/// self
Expand All @@ -636,10 +649,22 @@ shr_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
/// Foo[Foo];
/// }
/// ```
#[cfg(not(stage0))] // NOTE(stage0) remove cfg after a snapshot
#[lang="index"]
pub trait Index<Sized? Index, Sized? Result> for Sized? {
pub trait Index<Sized? Index> for Sized? {
type Sized? Output;

/// The method for the indexing (`Foo[Bar]`) operation
fn index<'a>(&'a self, index: &Index) -> &'a Result;
fn index<'a>(&'a self, index: &Index) -> &'a Self::Output;
}

// NOTE(stage0) remove trait after a snapshot
#[cfg(stage0)]
#[allow(missing_docs)]
#[lang="index_mut"]
pub trait IndexMut<Sized? Index, Sized? Result> for Sized? {
/// The method for the indexing (`Foo[Bar]`) operation
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
}

/// The `IndexMut` trait is used to specify the functionality of indexing
Expand All @@ -651,12 +676,16 @@ pub trait Index<Sized? Index, Sized? Result> for Sized? {
/// calling `index_mut`, and therefore, `main` prints `Indexing!`.
///
/// ```
/// #![feature(associated_types)]
///
/// use std::ops::IndexMut;
///
/// #[deriving(Copy)]
/// struct Foo;
///
/// impl IndexMut<Foo, Foo> for Foo {
/// impl IndexMut<Foo> for Foo {
/// type Output = Foo;
///
/// fn index_mut<'a>(&'a mut self, _index: &Foo) -> &'a mut Foo {
/// println!("Indexing!");
/// self
Expand All @@ -667,10 +696,13 @@ pub trait Index<Sized? Index, Sized? Result> for Sized? {
/// &mut Foo[Foo];
/// }
/// ```
#[cfg(not(stage0))] // NOTE(stage0) remove cfg after a snapshot
#[lang="index_mut"]
pub trait IndexMut<Sized? Index, Sized? Result> for Sized? {
pub trait IndexMut<Sized? Index> for Sized? {
type Sized? Output;

/// The method for the indexing (`Foo[Bar]`) operation
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output;
}

/// The `Slice` trait is used to specify the functionality of slicing operations
Expand Down
26 changes: 26 additions & 0 deletions src/libcore/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,8 @@ impl<T> SliceExt for [T] {
}
}

// NOTE(stage0) remove impl after a snapshot
#[cfg(stage0)]
impl<T> ops::Index<uint, T> for [T] {
fn index(&self, &index: &uint) -> &T {
assert!(index < self.len());
Expand All @@ -539,6 +541,19 @@ impl<T> ops::Index<uint, T> for [T] {
}
}

#[cfg(not(stage0))] // NOTE(stage0) remove cfg after a snapshot
impl<T> ops::Index<uint> for [T] {
type Output = T;

fn index(&self, &index: &uint) -> &T {
assert!(index < self.len());

unsafe { mem::transmute(self.repr().data.offset(index as int)) }
}
}

// NOTE(stage0) remove impl after a snapshot
#[cfg(stage0)]
impl<T> ops::IndexMut<uint, T> for [T] {
fn index_mut(&mut self, &index: &uint) -> &mut T {
assert!(index < self.len());
Expand All @@ -547,6 +562,17 @@ impl<T> ops::IndexMut<uint, T> for [T] {
}
}

#[cfg(not(stage0))] // NOTE(stage0) remove cfg after a snapshot
impl<T> ops::IndexMut<uint> for [T] {
type Output = T;

fn index_mut(&mut self, &index: &uint) -> &mut T {
assert!(index < self.len());

unsafe { mem::transmute(self.repr().data.offset(index as int)) }
}
}

impl<T> ops::Slice<uint, [T]> for [T] {
#[inline]
fn as_slice_<'a>(&'a self) -> &'a [T] {
Expand Down
11 changes: 5 additions & 6 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2524,7 +2524,6 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
}

let input_ty = fcx.infcx().next_ty_var();
let return_ty = fcx.infcx().next_ty_var();

// Try `IndexMut` first, if preferred.
let method = match (lvalue_pref, fcx.tcx().lang_items.index_mut_trait()) {
Expand All @@ -2536,7 +2535,7 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
trait_did,
adjustment.clone(),
adjusted_ty,
Some(vec![input_ty, return_ty]))
Some(vec![input_ty]))
}
_ => None,
};
Expand All @@ -2551,17 +2550,17 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
trait_did,
adjustment,
adjusted_ty,
Some(vec![input_ty, return_ty]))
Some(vec![input_ty]))
}
(method, _) => method,
};

// If some lookup succeeds, write callee into table and extract index/element
// type from the method signature.
// If some lookup succeeded, install method in table
method.map(|method| {
make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method));
(input_ty, return_ty)
method.and_then(|method| {
make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)).
map(|ret| (input_ty, ret.ty))
})
}

Expand Down
Loading