Skip to content

Commit 2abdeff

Browse files
committed
---
yaml --- r: 235414 b: refs/heads/stable c: f900551 h: refs/heads/master v: v3
1 parent 3324aeb commit 2abdeff

File tree

5 files changed

+109
-1
lines changed

5 files changed

+109
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 90d61d828f82a830b9edc202dd28bb5b4defc7e9
32+
refs/heads/stable: f9005512a9d84f469b30f0d469ccc401607ce64c
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/libcollections/str.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,14 @@ impl str {
546546
core_str::StrExt::slice_unchecked(self, begin, end)
547547
}
548548

549+
/// Takes a bytewise mutable slice from a string.
550+
///
551+
/// Same as `slice_unchecked`, but works with `&mut str` instead of `&str`.
552+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
553+
pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
554+
core_str::StrExt::slice_mut_unchecked(self, begin, end)
555+
}
556+
549557
/// Returns a slice of the string from the character range [`begin`..`end`).
550558
///
551559
/// That is, start at the `begin`-th code point of the string and continue

branches/stable/src/libcollections/string.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,38 @@ impl ops::Index<ops::RangeFull> for String {
979979
}
980980
}
981981

982+
#[cfg(not(stage0))]
983+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
984+
impl ops::IndexMut<ops::Range<usize>> for String {
985+
#[inline]
986+
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str {
987+
&mut self[..][index]
988+
}
989+
}
990+
#[cfg(not(stage0))]
991+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
992+
impl ops::IndexMut<ops::RangeTo<usize>> for String {
993+
#[inline]
994+
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str {
995+
&mut self[..][index]
996+
}
997+
}
998+
#[cfg(not(stage0))]
999+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
1000+
impl ops::IndexMut<ops::RangeFrom<usize>> for String {
1001+
#[inline]
1002+
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {
1003+
&mut self[..][index]
1004+
}
1005+
}
1006+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
1007+
impl ops::IndexMut<ops::RangeFull> for String {
1008+
#[inline]
1009+
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {
1010+
unsafe { mem::transmute(&mut *self.vec) }
1011+
}
1012+
}
1013+
9821014
#[stable(feature = "rust1", since = "1.0.0")]
9831015
impl ops::Deref for String {
9841016
type Target = str;

branches/stable/src/libcore/str/mod.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,23 @@ mod traits {
11161116
}
11171117
}
11181118

1119+
/// Returns a mutable slice of the given string from the byte range
1120+
/// [`begin`..`end`).
1121+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
1122+
impl ops::IndexMut<ops::Range<usize>> for str {
1123+
#[inline]
1124+
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str {
1125+
// is_char_boundary checks that the index is in [0, .len()]
1126+
if index.start <= index.end &&
1127+
self.is_char_boundary(index.start) &&
1128+
self.is_char_boundary(index.end) {
1129+
unsafe { self.slice_mut_unchecked(index.start, index.end) }
1130+
} else {
1131+
super::slice_error_fail(self, index.start, index.end)
1132+
}
1133+
}
1134+
}
1135+
11191136
/// Returns a slice of the string from the beginning to byte
11201137
/// `end`.
11211138
///
@@ -1138,6 +1155,21 @@ mod traits {
11381155
}
11391156
}
11401157

1158+
/// Returns a mutable slice of the string from the beginning to byte
1159+
/// `end`.
1160+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
1161+
impl ops::IndexMut<ops::RangeTo<usize>> for str {
1162+
#[inline]
1163+
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str {
1164+
// is_char_boundary checks that the index is in [0, .len()]
1165+
if self.is_char_boundary(index.end) {
1166+
unsafe { self.slice_mut_unchecked(0, index.end) }
1167+
} else {
1168+
super::slice_error_fail(self, 0, index.end)
1169+
}
1170+
}
1171+
}
1172+
11411173
/// Returns a slice of the string from `begin` to its end.
11421174
///
11431175
/// Equivalent to `self[begin .. self.len()]`.
@@ -1159,6 +1191,21 @@ mod traits {
11591191
}
11601192
}
11611193

1194+
/// Returns a slice of the string from `begin` to its end.
1195+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
1196+
impl ops::IndexMut<ops::RangeFrom<usize>> for str {
1197+
#[inline]
1198+
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {
1199+
// is_char_boundary checks that the index is in [0, .len()]
1200+
if self.is_char_boundary(index.start) {
1201+
let len = self.len();
1202+
unsafe { self.slice_mut_unchecked(index.start, len) }
1203+
} else {
1204+
super::slice_error_fail(self, index.start, self.len())
1205+
}
1206+
}
1207+
}
1208+
11621209
#[stable(feature = "rust1", since = "1.0.0")]
11631210
impl ops::Index<ops::RangeFull> for str {
11641211
type Output = str;
@@ -1168,6 +1215,14 @@ mod traits {
11681215
self
11691216
}
11701217
}
1218+
1219+
#[stable(feature = "derefmut_for_string", since = "1.2.0")]
1220+
impl ops::IndexMut<ops::RangeFull> for str {
1221+
#[inline]
1222+
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {
1223+
self
1224+
}
1225+
}
11711226
}
11721227

11731228
/// Methods for string slices
@@ -1204,6 +1259,7 @@ pub trait StrExt {
12041259
fn char_len(&self) -> usize;
12051260
fn slice_chars<'a>(&'a self, begin: usize, end: usize) -> &'a str;
12061261
unsafe fn slice_unchecked<'a>(&'a self, begin: usize, end: usize) -> &'a str;
1262+
unsafe fn slice_mut_unchecked<'a>(&'a mut self, begin: usize, end: usize) -> &'a mut str;
12071263
fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
12081264
fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
12091265
where P::Searcher: ReverseSearcher<'a>;
@@ -1379,6 +1435,14 @@ impl StrExt for str {
13791435
})
13801436
}
13811437

1438+
#[inline]
1439+
unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
1440+
mem::transmute(Slice {
1441+
data: self.as_ptr().offset(begin as isize),
1442+
len: end - begin,
1443+
})
1444+
}
1445+
13821446
#[inline]
13831447
fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
13841448
pat.is_prefix_of(self)

branches/stable/src/libstd/ascii.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,10 @@ mod tests {
583583
test!('!', '!');
584584
test!(b"h\xc3\xa9".to_vec(), b"H\xc3\xa9");
585585
test!("hıKß".to_string(), "HıKß");
586+
587+
let mut x = "Hello".to_string();
588+
x[..3].make_ascii_uppercase(); // Test IndexMut on String.
589+
assert_eq!(x, "HELlo")
586590
}
587591

588592
#[test]

0 commit comments

Comments
 (0)