diff options
| author | bors <bors@rust-lang.org> | 2018-04-21 18:42:41 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-21 18:42:41 +0000 |
| commit | 699eb95ae3dae023cddca85facf6660b196bd0d1 (patch) | |
| tree | 3832605aa9880861a33e4c5b86e4c7398d9a4337 | |
| parent | d2577ca1ec1449bd83d05e540c57447574ccaa28 (diff) | |
| parent | 90b361b3a748e9fb01cd9aec7b83edca2d9e996e (diff) | |
| download | rust-699eb95ae3dae023cddca85facf6660b196bd0d1.tar.gz rust-699eb95ae3dae023cddca85facf6660b196bd0d1.zip | |
Auto merge of #50039 - ExpHP:quick-50002, r=alexcrichton
smaller PR just to fix #50002 I pulled this out of #50010 to make it easier to backport to beta if necessary, considering that inclusive range syntax is stabilizing soon (?). It fixes a bug in `<str>::index_mut` with `(..=end)` ranges (#50002), which prior to this fix was not only unusable but also UB in the cases where it "worked" (it gave improperly truncated UTF-8). (not that I can imagine why anybody would *use* `<str>::index_mut`... but I'm not here to judge)
| -rw-r--r-- | src/liballoc/tests/str.rs | 30 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 9 |
2 files changed, 32 insertions, 7 deletions
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index a3f4c385fe2..a03b61ec97e 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -402,6 +402,36 @@ fn test_str_get_maxinclusive() { } #[test] +fn test_str_slice_rangetoinclusive_ok() { + let s = "abcαβγ"; + assert_eq!(&s[..=2], "abc"); + assert_eq!(&s[..=4], "abcα"); +} + +#[test] +#[should_panic] +fn test_str_slice_rangetoinclusive_notok() { + let s = "abcαβγ"; + &s[..=3]; +} + +#[test] +fn test_str_slicemut_rangetoinclusive_ok() { + let mut s = "abcαβγ".to_owned(); + let s: &mut str = &mut s; + assert_eq!(&mut s[..=2], "abc"); + assert_eq!(&mut s[..=4], "abcα"); +} + +#[test] +#[should_panic] +fn test_str_slicemut_rangetoinclusive_notok() { + let mut s = "abcαβγ".to_owned(); + let s: &mut str = &mut s; + &mut s[..=3]; +} + +#[test] fn test_is_char_boundary() { let s = "ศไทย中华Việt Nam β-release 🐱123"; assert!(s.is_char_boundary(0)); diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f1fe23092de..5b52119d031 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2100,18 +2100,13 @@ mod traits { fn index(self, slice: &str) -> &Self::Output { assert!(self.end != usize::max_value(), "attempted to index str up to maximum usize"); - let end = self.end + 1; - self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, 0, end)) + (..self.end+1).index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { assert!(self.end != usize::max_value(), "attempted to index str up to maximum usize"); - if slice.is_char_boundary(self.end) { - unsafe { self.get_unchecked_mut(slice) } - } else { - super::slice_error_fail(slice, 0, self.end + 1) - } + (..self.end+1).index_mut(slice) } } |
