diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-03-23 15:10:50 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-03-23 15:10:50 -0700 |
| commit | 753efb5042563dd34a4a524197fa14a129ddf449 (patch) | |
| tree | c7f2301e6ba8d7e0e6f16674905a36c55b853085 /src/libstd | |
| parent | 388e5aee1e3df9e25f69815ffebfaa39e2167b5f (diff) | |
| parent | 57cf2decf755c6eea3275e2a87862756eb8c62ca (diff) | |
| download | rust-753efb5042563dd34a4a524197fa14a129ddf449.tar.gz rust-753efb5042563dd34a4a524197fa14a129ddf449.zip | |
rollup merge of #23601: nikomatsakis/by-value-index
This is a [breaking-change]. When indexing a generic map (hashmap, etc) using the `[]` operator, it is now necessary to borrow explicitly, so change `map[key]` to `map[&key]` (consistent with the `get` routine). However, indexing of string-valued maps with constant strings can now be written `map["abc"]`. r? @japaric cc @aturon @Gankro
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/collections/hash/map.rs | 24 | ||||
| -rw-r--r-- | src/libstd/ffi/os_str.rs | 12 | ||||
| -rw-r--r-- | src/libstd/sys/common/wtf8.rs | 79 | ||||
| -rw-r--r-- | src/libstd/thread/local.rs | 2 |
4 files changed, 112 insertions, 5 deletions
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 9139e182ce4..86664d7eb0c 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1088,7 +1088,7 @@ impl<K, V, S> HashMap<K, V, S> /// Some(x) => *x = "b", /// None => (), /// } - /// assert_eq!(map[1], "b"); + /// assert_eq!(map[&1], "b"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> @@ -1111,7 +1111,7 @@ impl<K, V, S> HashMap<K, V, S> /// /// map.insert(37, "b"); /// assert_eq!(map.insert(37, "c"), Some("b")); - /// assert_eq!(map[37], "c"); + /// assert_eq!(map[&37], "c"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(&mut self, k: K, v: V) -> Option<V> { @@ -1244,6 +1244,7 @@ impl<K, V, S> Default for HashMap<K, V, S> } } +#[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S> where K: Eq + Hash + Borrow<Q>, @@ -1258,6 +1259,21 @@ impl<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S> } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap<K, V, S> + where K: Eq + Hash + Borrow<Q>, + Q: Eq + Hash, + S: HashState, +{ + type Output = V; + + #[inline] + fn index(&self, index: &Q) -> &V { + self.get(index).expect("no entry found for key") + } +} + /// HashMap iterator. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, K: 'a, V: 'a> { @@ -2185,7 +2201,7 @@ mod test_map { map.insert(2, 1); map.insert(3, 4); - assert_eq!(map[2], 1); + assert_eq!(map[&2], 1); } #[test] @@ -2197,7 +2213,7 @@ mod test_map { map.insert(2, 1); map.insert(3, 4); - map[4]; + map[&4]; } #[test] diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 4d411046632..5851c6e2998 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -133,6 +133,7 @@ impl<'a> From<&'a OsStr> for OsString { } } +#[cfg(stage0)] #[stable(feature = "rust1", since = "1.0.0")] impl ops::Index<ops::RangeFull> for OsString { type Output = OsStr; @@ -143,6 +144,17 @@ impl ops::Index<ops::RangeFull> for OsString { } } +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +impl ops::Index<ops::RangeFull> for OsString { + type Output = OsStr; + + #[inline] + fn index(&self, _index: ops::RangeFull) -> &OsStr { + unsafe { mem::transmute(self.inner.as_slice()) } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ops::Deref for OsString { type Target = OsStr; diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 3cc91bf54b4..9f3dae34c7a 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -634,6 +634,7 @@ impl Wtf8 { /// /// Panics when `begin` and `end` do not point to code point boundaries, /// or point beyond the end of the string. +#[cfg(stage0)] impl ops::Index<ops::Range<usize>> for Wtf8 { type Output = Wtf8; @@ -650,12 +651,36 @@ impl ops::Index<ops::Range<usize>> for Wtf8 { } } +/// Return a slice of the given string for the byte range [`begin`..`end`). +/// +/// # Panics +/// +/// Panics when `begin` and `end` do not point to code point boundaries, +/// or point beyond the end of the string. +#[cfg(not(stage0))] +impl ops::Index<ops::Range<usize>> for Wtf8 { + type Output = Wtf8; + + #[inline] + fn index(&self, range: ops::Range<usize>) -> &Wtf8 { + // is_code_point_boundary checks that the index is in [0, .len()] + if range.start <= range.end && + is_code_point_boundary(self, range.start) && + is_code_point_boundary(self, range.end) { + unsafe { slice_unchecked(self, range.start, range.end) } + } else { + slice_error_fail(self, range.start, range.end) + } + } +} + /// Return a slice of the given string from byte `begin` to its end. /// /// # Panics /// /// Panics when `begin` is not at a code point boundary, /// or is beyond the end of the string. +#[cfg(stage0)] impl ops::Index<ops::RangeFrom<usize>> for Wtf8 { type Output = Wtf8; @@ -670,12 +695,34 @@ impl ops::Index<ops::RangeFrom<usize>> for Wtf8 { } } +/// Return a slice of the given string from byte `begin` to its end. +/// +/// # Panics +/// +/// Panics when `begin` is not at a code point boundary, +/// or is beyond the end of the string. +#[cfg(not(stage0))] +impl ops::Index<ops::RangeFrom<usize>> for Wtf8 { + type Output = Wtf8; + + #[inline] + fn index(&self, range: ops::RangeFrom<usize>) -> &Wtf8 { + // is_code_point_boundary checks that the index is in [0, .len()] + if is_code_point_boundary(self, range.start) { + unsafe { slice_unchecked(self, range.start, self.len()) } + } else { + slice_error_fail(self, range.start, self.len()) + } + } +} + /// Return a slice of the given string from its beginning to byte `end`. /// /// # Panics /// /// Panics when `end` is not at a code point boundary, /// or is beyond the end of the string. +#[cfg(stage0)] impl ops::Index<ops::RangeTo<usize>> for Wtf8 { type Output = Wtf8; @@ -690,6 +737,28 @@ impl ops::Index<ops::RangeTo<usize>> for Wtf8 { } } +/// Return a slice of the given string from its beginning to byte `end`. +/// +/// # Panics +/// +/// Panics when `end` is not at a code point boundary, +/// or is beyond the end of the string. +#[cfg(not(stage0))] +impl ops::Index<ops::RangeTo<usize>> for Wtf8 { + type Output = Wtf8; + + #[inline] + fn index(&self, range: ops::RangeTo<usize>) -> &Wtf8 { + // is_code_point_boundary checks that the index is in [0, .len()] + if is_code_point_boundary(self, range.end) { + unsafe { slice_unchecked(self, 0, range.end) } + } else { + slice_error_fail(self, 0, range.end) + } + } +} + +#[cfg(stage0)] impl ops::Index<ops::RangeFull> for Wtf8 { type Output = Wtf8; @@ -699,6 +768,16 @@ impl ops::Index<ops::RangeFull> for Wtf8 { } } +#[cfg(not(stage0))] +impl ops::Index<ops::RangeFull> for Wtf8 { + type Output = Wtf8; + + #[inline] + fn index(&self, _range: ops::RangeFull) -> &Wtf8 { + self + } +} + #[inline] fn decode_surrogate(second_byte: u8, third_byte: u8) -> u16 { // The first byte is assumed to be 0xED diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 023c6b26cbc..1bf1b09681c 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -716,7 +716,7 @@ mod dynamic_tests { thread_local!(static FOO: RefCell<HashMap<i32, i32>> = map()); FOO.with(|map| { - assert_eq!(map.borrow()[1], 2); + assert_eq!(map.borrow()[&1], 2); }); } |
