From 46fef766b0dc3717937911f0f67c9f1ee2a7f21e Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Sun, 28 Jan 2018 14:24:19 -0500 Subject: [PATCH 1/5] Have Vec use slice's implementations of Index and IndexMut --- src/liballoc/vec.rs | 130 ++------------------------------------------ 1 file changed, 5 insertions(+), 125 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 3c9b6b94b4405..9c6b10c32f1e4 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1527,11 +1527,11 @@ impl Hash for Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl Index for Vec { - type Output = T; +impl Index for Vec where [T]: Index { + type Output = <[T] as Index>::Output; #[inline] - fn index(&self, index: usize) -> &T { + fn index(&self, index: I) -> &Self::Output { // NB built-in indexing via `&[T]` &(**self)[index] } @@ -1539,134 +1539,14 @@ impl Index for Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl IndexMut for Vec { +impl IndexMut for Vec where [T]: IndexMut { #[inline] - fn index_mut(&mut self, index: usize) -> &mut T { + fn index_mut(&mut self, index: I) -> &mut Self::Output { // NB built-in indexing via `&mut [T]` &mut (**self)[index] } } -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::Range) -> &[T] { - Index::index(&**self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::RangeTo) -> &[T] { - Index::index(&**self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::RangeFrom) -> &[T] { - Index::index(&**self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index for Vec { - type Output = [T]; - - #[inline] - fn index(&self, _index: ops::RangeFull) -> &[T] { - self - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::RangeInclusive) -> &[T] { - Index::index(&**self, index) - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::Index> for Vec { - type Output = [T]; - - #[inline] - fn index(&self, index: ops::RangeToInclusive) -> &[T] { - Index::index(&**self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::Range) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::RangeTo) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::RangeFrom) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut for Vec { - #[inline] - fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] { - self - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl ops::IndexMut> for Vec { - #[inline] - fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut [T] { - IndexMut::index_mut(&mut **self, index) - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for Vec { type Target = [T]; From 2db05f04bebd8a8cfbdb323fbd6d3341aee551d9 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Mon, 29 Jan 2018 15:01:52 -0500 Subject: [PATCH 2/5] Update UI test --- src/test/ui/index-help.stderr | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr index f4dde95b1046c..1b5d28d5bb1b1 100644 --- a/src/test/ui/index-help.stderr +++ b/src/test/ui/index-help.stderr @@ -1,10 +1,11 @@ -error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::ops::Index` is not satisfied +error[E0277]: the trait bound `i32: std::slice::SliceIndex<[{integer}]>` is not satisfied --> $DIR/index-help.rs:13:5 | LL | x[0i32]; //~ ERROR E0277 - | ^^^^^^^ vector indices are of type `usize` or ranges of `usize` + | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` | - = help: the trait `std::ops::Index` is not implemented for `std::vec::Vec<{integer}>` + = help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `i32` + = note: required because of the requirements on the impl of `std::ops::Index` for `[{integer}]` error: aborting due to previous error From 45bdf9cbeec3788c29d8958dc661dd449bb7247c Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Mon, 29 Jan 2018 15:02:44 -0500 Subject: [PATCH 3/5] Update comments --- src/liballoc/vec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 9c6b10c32f1e4..83538e5acd4c1 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1532,7 +1532,7 @@ impl Index for Vec where [T]: Index { #[inline] fn index(&self, index: I) -> &Self::Output { - // NB built-in indexing via `&[T]` + // NB indexing via implementation on slice &(**self)[index] } } @@ -1542,7 +1542,7 @@ impl Index for Vec where [T]: Index { impl IndexMut for Vec where [T]: IndexMut { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { - // NB built-in indexing via `&mut [T]` + // NB indexing via implementation on slice &mut (**self)[index] } } From ae73a210814bdf50d72a95568eb8c9c96772c641 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Wed, 31 Jan 2018 20:14:17 -0500 Subject: [PATCH 4/5] Update compile fail test error messages --- src/test/compile-fail/integral-indexing.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/compile-fail/integral-indexing.rs b/src/test/compile-fail/integral-indexing.rs index 659b08b55a00a..4b01afb8131b7 100644 --- a/src/test/compile-fail/integral-indexing.rs +++ b/src/test/compile-fail/integral-indexing.rs @@ -13,10 +13,10 @@ pub fn main() { let s: String = "abcdef".to_string(); v[3_usize]; v[3]; - v[3u8]; //~ERROR : std::ops::Index` is not satisfied - v[3i8]; //~ERROR : std::ops::Index` is not satisfied - v[3u32]; //~ERROR : std::ops::Index` is not satisfied - v[3i32]; //~ERROR : std::ops::Index` is not satisfied + v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied + v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied + v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied + v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied s.as_bytes()[3_usize]; s.as_bytes()[3]; s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied From 370df40dab8df9f3c0b10bb7396225b8d24869b3 Mon Sep 17 00:00:00 2001 From: Jonathan Behrens Date: Fri, 2 Mar 2018 23:23:00 -0500 Subject: [PATCH 5/5] Don't have Vec delegate to [T]'s bounds for indexing --- src/liballoc/vec.rs | 18 +++++++++++------- src/test/ui/index-help.stderr | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 83538e5acd4c1..feed7c8699a3e 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1527,23 +1527,27 @@ impl Hash for Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl Index for Vec where [T]: Index { - type Output = <[T] as Index>::Output; +impl Index for Vec +where + I: ::core::slice::SliceIndex<[T]>, +{ + type Output = I::Output; #[inline] fn index(&self, index: I) -> &Self::Output { - // NB indexing via implementation on slice - &(**self)[index] + Index::index(&**self, index) } } #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented = "vector indices are of type `usize` or ranges of `usize`"] -impl IndexMut for Vec where [T]: IndexMut { +impl IndexMut for Vec +where + I: ::core::slice::SliceIndex<[T]>, +{ #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { - // NB indexing via implementation on slice - &mut (**self)[index] + IndexMut::index_mut(&mut **self, index) } } diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr index 1b5d28d5bb1b1..ae3cd529ac42e 100644 --- a/src/test/ui/index-help.stderr +++ b/src/test/ui/index-help.stderr @@ -5,7 +5,7 @@ LL | x[0i32]; //~ ERROR E0277 | ^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `i32` - = note: required because of the requirements on the impl of `std::ops::Index` for `[{integer}]` + = note: required because of the requirements on the impl of `std::ops::Index` for `std::vec::Vec<{integer}>` error: aborting due to previous error