Skip to content

Commit 90f4348

Browse files
committed
---
yaml --- r: 228343 b: refs/heads/try c: f900551 h: refs/heads/master i: 228341: dec9411 228339: 26d9ac6 228335: 96786d2 v: v3
1 parent 87e487f commit 90f4348

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
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 90d61d828f82a830b9edc202dd28bb5b4defc7e9
4+
refs/heads/try: f9005512a9d84f469b30f0d469ccc401607ce64c
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/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/try/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/try/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/try/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)