about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/macros.rs29
-rw-r--r--src/liballoc/string.rs109
-rw-r--r--src/liballoc/tests/string.rs22
3 files changed, 46 insertions, 114 deletions
diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs
index 763f04fcd0d..43ebaa4fbdb 100644
--- a/src/liballoc/macros.rs
+++ b/src/liballoc/macros.rs
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/// Creates a `Vec` containing the arguments.
+/// Creates a [`Vec`] containing the arguments.
 ///
 /// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
 /// There are two forms of this macro:
 ///
-/// - Create a `Vec` containing a given list of elements:
+/// - Create a [`Vec`] containing a given list of elements:
 ///
 /// ```
 /// let v = vec![1, 2, 3];
@@ -22,7 +22,7 @@
 /// assert_eq!(v[2], 3);
 /// ```
 ///
-/// - Create a `Vec` from a given element and size:
+/// - Create a [`Vec`] from a given element and size:
 ///
 /// ```
 /// let v = vec![1; 3];
@@ -30,14 +30,17 @@
 /// ```
 ///
 /// Note that unlike array expressions this syntax supports all elements
-/// which implement `Clone` and the number of elements doesn't have to be
+/// which implement [`Clone`] and the number of elements doesn't have to be
 /// a constant.
 ///
-/// This will use `clone()` to duplicate an expression, so one should be careful
+/// This will use `clone` to duplicate an expression, so one should be careful
 /// using this with types having a nonstandard `Clone` implementation. For
 /// example, `vec![Rc::new(1); 5]` will create a vector of five references
 /// to the same boxed integer value, not five references pointing to independently
 /// boxed integers.
+///
+/// [`Vec`]: ../std/vec/struct.Vec.html
+/// [`Clone`]: ../std/clone/trait.Clone.html
 #[cfg(not(test))]
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -67,10 +70,22 @@ macro_rules! vec {
     ($($x:expr,)*) => (vec![$($x),*])
 }
 
-/// Use the syntax described in `std::fmt` to create a value of type `String`.
-/// See [`std::fmt`][fmt] for more information.
+/// Creates a `String` using interpolation of runtime expressions.
+///
+/// The first argument `format!` recieves is a format string.  This must be a string
+/// literal.  The power of the formatting string is in the `{}`s contained.
+///
+/// Additional parameters passed to `format!` replace the `{}`s within the
+/// formatting string in the order given unless named or positional parameters
+/// are used, see [`std::fmt`][fmt] for more information.
+///
+/// A common use for `format!` is concatenation and interpolation of strings.
+/// The same convention is used with [`print!`] and [`write!`] macros,
+/// depending on the intended destination of the string.
 ///
 /// [fmt]: ../std/fmt/index.html
+/// [`print!`]: ../std/macro.print.html
+/// [`write!`]: ../std/macro.write.html
 ///
 /// # Panics
 ///
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index b1919c7c968..ddb23b2ef37 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -1392,11 +1392,11 @@ impl String {
     }
 
     /// Creates a splicing iterator that removes the specified range in the string,
-    /// replaces with the given string, and yields the removed chars.
-    /// The given string doesn’t need to be the same length as the range.
+    /// and replaces it with the given string.
+    /// The given string doesn't need to be the same length as the range.
     ///
-    /// Note: The element range is removed when the [`Splice`] is dropped,
-    /// even if the iterator is not consumed until the end.
+    /// Note: Unlike [`Vec::splice`], the replacement happens eagerly, and this
+    /// method does not return the removed chars.
     ///
     /// # Panics
     ///
@@ -1404,7 +1404,7 @@ impl String {
     /// boundary, or if they're out of bounds.
     ///
     /// [`char`]: ../../std/primitive.char.html
-    /// [`Splice`]: ../../std/string/struct.Splice.html
+    /// [`Vec::splice`]: ../../std/vec/struct.Vec.html#method.splice
     ///
     /// # Examples
     ///
@@ -1416,45 +1416,32 @@ impl String {
     /// let beta_offset = s.find('β').unwrap_or(s.len());
     ///
     /// // Replace the range up until the β from the string
-    /// let t: String = s.splice(..beta_offset, "Α is capital alpha; ").collect();
-    /// assert_eq!(t, "α is alpha, ");
+    /// s.splice(..beta_offset, "Α is capital alpha; ");
     /// assert_eq!(s, "Α is capital alpha; β is beta");
     /// ```
     #[unstable(feature = "splice", reason = "recently added", issue = "32310")]
-    pub fn splice<'a, 'b, R>(&'a mut self, range: R, replace_with: &'b str) -> Splice<'a, 'b>
+    pub fn splice<R>(&mut self, range: R, replace_with: &str)
         where R: RangeArgument<usize>
     {
         // Memory safety
         //
         // The String version of Splice does not have the memory safety issues
         // of the vector version. The data is just plain bytes.
-        // Because the range removal happens in Drop, if the Splice iterator is leaked,
-        // the removal will not happen.
-        let len = self.len();
-        let start = match range.start() {
-             Included(&n) => n,
-             Excluded(&n) => n + 1,
-             Unbounded => 0,
+
+        match range.start() {
+             Included(&n) => assert!(self.is_char_boundary(n)),
+             Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
+             Unbounded => {},
         };
-        let end = match range.end() {
-             Included(&n) => n + 1,
-             Excluded(&n) => n,
-             Unbounded => len,
+        match range.end() {
+             Included(&n) => assert!(self.is_char_boundary(n + 1)),
+             Excluded(&n) => assert!(self.is_char_boundary(n)),
+             Unbounded => {},
         };
 
-        // Take out two simultaneous borrows. The &mut String won't be accessed
-        // until iteration is over, in Drop.
-        let self_ptr = self as *mut _;
-        // slicing does the appropriate bounds checks
-        let chars_iter = self[start..end].chars();
-
-        Splice {
-            start,
-            end,
-            iter: chars_iter,
-            string: self_ptr,
-            replace_with,
-        }
+        unsafe {
+            self.as_mut_vec()
+        }.splice(range, replace_with.bytes());
     }
 
     /// Converts this `String` into a [`Box`]`<`[`str`]`>`.
@@ -2241,61 +2228,3 @@ impl<'a> DoubleEndedIterator for Drain<'a> {
 
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a> FusedIterator for Drain<'a> {}
-
-/// A splicing iterator for `String`.
-///
-/// This struct is created by the [`splice()`] method on [`String`]. See its
-/// documentation for more.
-///
-/// [`splice()`]: struct.String.html#method.splice
-/// [`String`]: struct.String.html
-#[derive(Debug)]
-#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
-pub struct Splice<'a, 'b> {
-    /// Will be used as &'a mut String in the destructor
-    string: *mut String,
-    /// Start of part to remove
-    start: usize,
-    /// End of part to remove
-    end: usize,
-    /// Current remaining range to remove
-    iter: Chars<'a>,
-    replace_with: &'b str,
-}
-
-#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
-unsafe impl<'a, 'b> Sync for Splice<'a, 'b> {}
-#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
-unsafe impl<'a, 'b> Send for Splice<'a, 'b> {}
-
-#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
-impl<'a, 'b> Drop for Splice<'a, 'b> {
-    fn drop(&mut self) {
-        unsafe {
-            let vec = (*self.string).as_mut_vec();
-            vec.splice(self.start..self.end, self.replace_with.bytes());
-        }
-    }
-}
-
-#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
-impl<'a, 'b> Iterator for Splice<'a, 'b> {
-    type Item = char;
-
-    #[inline]
-    fn next(&mut self) -> Option<char> {
-        self.iter.next()
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.iter.size_hint()
-    }
-}
-
-#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
-impl<'a, 'b> DoubleEndedIterator for Splice<'a, 'b> {
-    #[inline]
-    fn next_back(&mut self) -> Option<char> {
-        self.iter.next_back()
-    }
-}
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index f5c124c6b44..6aba18ddf49 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -442,9 +442,8 @@ fn test_drain() {
 #[test]
 fn test_splice() {
     let mut s = "Hello, world!".to_owned();
-    let t: String = s.splice(7..12, "世界").collect();
+    s.splice(7..12, "世界");
     assert_eq!(s, "Hello, 世界!");
-    assert_eq!(t, "world");
 }
 
 #[test]
@@ -457,12 +456,10 @@ fn test_splice_char_boundary() {
 #[test]
 fn test_splice_inclusive_range() {
     let mut v = String::from("12345");
-    let t: String = v.splice(2...3, "789").collect();
+    v.splice(2...3, "789");
     assert_eq!(v, "127895");
-    assert_eq!(t, "34");
-    let t2: String = v.splice(1...2, "A").collect();
+    v.splice(1...2, "A");
     assert_eq!(v, "1A895");
-    assert_eq!(t2, "27");
 }
 
 #[test]
@@ -482,24 +479,15 @@ fn test_splice_inclusive_out_of_bounds() {
 #[test]
 fn test_splice_empty() {
     let mut s = String::from("12345");
-    let t: String = s.splice(1..2, "").collect();
+    s.splice(1..2, "");
     assert_eq!(s, "1345");
-    assert_eq!(t, "2");
 }
 
 #[test]
 fn test_splice_unbounded() {
     let mut s = String::from("12345");
-    let t: String = s.splice(.., "").collect();
+    s.splice(.., "");
     assert_eq!(s, "");
-    assert_eq!(t, "12345");
-}
-
-#[test]
-fn test_splice_forget() {
-    let mut s = String::from("12345");
-    ::std::mem::forget(s.splice(2..4, "789"));
-    assert_eq!(s, "12345");
 }
 
 #[test]