]> git.lizzy.rs Git - rust.git/commitdiff
std: Tweak String implementations
authorAlex Crichton <alex@alexcrichton.com>
Wed, 7 Jan 2015 22:58:31 +0000 (14:58 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 7 Jan 2015 23:24:21 +0000 (15:24 -0800)
This commit performs a pass over the implementations of the new `String` trait
in the formatting module. Some implementations were removed as a conservative
move pending an upcoming convention about `String` implementations, and some
were added in order to retain consistency across the libraries. Specifically:

* All "smart pointers" implement `String` now, adding missing implementations
  for `Arc` and `Rc`.
* The `Vec<T>` and `[T]` types no longer implement `String`.
* The `*const T` and `*mut T` type no longer implement `String`.
* The `()` type no longer implements `String`.
* The `Path` type's `Show` implementation does not surround itself with `Path
  {}` (a minor tweak).

All implementations of `String` in this PR were also marked `#[stable]` to
indicate that the types will continue to implement the `String` trait regardless
of what it looks like.

22 files changed:
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/rc.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcore/borrow.rs
src/libcore/fmt/mod.rs
src/libcore/option.rs
src/librustdoc/html/format.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs
src/test/compile-fail/drop-with-active-borrows-2.rs
src/test/compile-fail/no-capture-arc.rs
src/test/compile-fail/no-reuse-move-arc.rs
src/test/compile-fail/packed-struct-generic-transmute.rs
src/test/run-pass/evec-slice.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/issue-17503.rs
src/test/run-pass/issue-5688.rs
src/test/run-pass/repeated-vector-syntax.rs
src/test/run-pass/vec-to_str.rs

index 5d47602b5e15c4eea7426c5929241625a81bb5ce..8a6afd2e2643abc5590d2d1e7418834f8e1bc078 100644 (file)
@@ -585,6 +585,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable]
+impl<T: fmt::String> fmt::String for Arc<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::String::fmt(&**self, f)
+    }
+}
+
 #[stable]
 impl<T: Default + Sync + Send> Default for Arc<T> {
     #[stable]
index d46f18abf97b481f781225bc42b7d291cc399f37..1943b1bd34b5b6ea7f980317cdc67b7d3917418f 100644 (file)
@@ -149,6 +149,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable]
 impl<T: ?Sized + fmt::String> fmt::String for Box<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::String::fmt(&**self, f)
index 67b254277101229ae9d8bab6de237e4fc28cf90d..867f70df7746a8f0dcf7caac30bf5a8104e86e2a 100644 (file)
@@ -611,6 +611,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable]
+impl<T: fmt::String> fmt::String for Rc<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::String::fmt(&**self, f)
+    }
+}
+
 /// A weak version of `Rc<T>`.
 ///
 /// Weak references do not count when determining if the inner value should be dropped.
index 59418f50e3c7d44b89a792a04121e97e5c783454..5bcb6be19bc0cd5b9a30ff5b1e06d8d266a1694d 100644 (file)
@@ -681,6 +681,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable]
 impl fmt::String for FromUtf8Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::String::fmt(&self.error, f)
@@ -693,6 +694,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable]
 impl fmt::String for FromUtf16Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::String::fmt("invalid utf-16: lone surrogate found", f)
@@ -805,7 +807,7 @@ fn default() -> String {
     }
 }
 
-#[experimental = "waiting on fmt stabilization"]
+#[stable]
 impl fmt::String for String {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::String::fmt(&**self, f)
@@ -1277,18 +1279,17 @@ fn test_simple_types() {
         assert_eq!(2u8.to_string(), "2");
         assert_eq!(true.to_string(), "true");
         assert_eq!(false.to_string(), "false");
-        assert_eq!(().to_string(), "()");
         assert_eq!(("hi".to_string()).to_string(), "hi");
     }
 
     #[test]
     fn test_vectors() {
         let x: Vec<int> = vec![];
-        assert_eq!(x.to_string(), "[]");
-        assert_eq!((vec![1i]).to_string(), "[1]");
-        assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]");
-        assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
-               "[[], [1], [1, 1]]");
+        assert_eq!(format!("{:?}", x), "[]");
+        assert_eq!(format!("{:?}", vec![1i]), "[1i]");
+        assert_eq!(format!("{:?}", vec![1i, 2, 3]), "[1i, 2i, 3i]");
+        assert!(format!("{:?}", vec![vec![], vec![1i], vec![1i, 1]]) ==
+               "[[], [1i], [1i, 1i]]");
     }
 
     #[test]
index 5fc3fafac9e229f3dcda6e96f2965285f86292ab..f01a34206e203aadf0c09b9b754dd83de6c4a25b 100644 (file)
@@ -1454,22 +1454,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[cfg(stage0)]
-#[experimental = "waiting on Show stability"]
-impl<T: fmt::Show> fmt::String for Vec<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::String::fmt(self.as_slice(), f)
-    }
-}
-
-#[cfg(not(stage0))]
-#[experimental = "waiting on Show stability"]
-impl<T: fmt::String> fmt::String for Vec<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::String::fmt(self.as_slice(), f)
-    }
-}
-
 impl<'a> fmt::Writer for Vec<u8> {
     fn write_str(&mut self, s: &str) -> fmt::Result {
         self.push_all(s.as_bytes());
index 31631355422964cce82aec6a145a3c897f824ed4..11f5e593462fb5ee6a47942beb664ee81366e7cb 100644 (file)
@@ -248,6 +248,7 @@ fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
     }
 }
 
+#[stable]
 impl<'a, T, B: ?Sized> fmt::String for Cow<'a, T, B> where
     B: fmt::String + ToOwned<T>,
     T: fmt::String,
index f9027f19068e435f51062e2745a642fa9db45d36..8cceb37b9a4b98a66ad105dc972201ad94307ef3 100644 (file)
@@ -219,6 +219,7 @@ fn fmt(&self, fmt: &mut Formatter) -> Result {
     }
 }
 
+#[stable]
 impl<'a> String for Arguments<'a> {
     fn fmt(&self, fmt: &mut Formatter) -> Result {
         write(fmt.buf, *self)
@@ -627,6 +628,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
     }
 }
 
+#[stable]
 impl String for bool {
     fn fmt(&self, f: &mut Formatter) -> Result {
         String::fmt(if *self { "true" } else { "false" }, f)
@@ -653,6 +655,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
     }
 }
 
+#[stable]
 impl String for str {
     fn fmt(&self, f: &mut Formatter) -> Result {
         f.pad(self)
@@ -680,6 +683,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
     }
 }
 
+#[stable]
 impl String for char {
     fn fmt(&self, f: &mut Formatter) -> Result {
         let mut utf8 = [0u8; 4];
@@ -725,6 +729,7 @@ fn fmt(&self, fmt: &mut Formatter) -> Result {
         }
     }
 
+    #[stable]
     impl String for $ty {
         fn fmt(&self, fmt: &mut Formatter) -> Result {
             use num::Float;
@@ -796,15 +801,9 @@ fn fmt(&self, fmt: &mut Formatter) -> Result {
 impl<T> Show for *const T {
     fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
 }
-impl<T> String for *const T {
-    fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
-}
 impl<T> Show for *mut T {
     fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
 }
-impl<T> String for *mut T {
-    fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) }
-}
 
 macro_rules! peel {
     ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* })
@@ -863,61 +862,12 @@ fn fmt(&self, f: &mut Formatter) -> Result {
     }
 }
 
-#[cfg(stage0)]
-impl<T: Show> String for [T] {
-    fn fmt(&self, f: &mut Formatter) -> Result {
-        if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
-            try!(write!(f, "["));
-        }
-        let mut is_first = true;
-        for x in self.iter() {
-            if is_first {
-                is_first = false;
-            } else {
-                try!(write!(f, ", "));
-            }
-            try!(write!(f, "{}", *x))
-        }
-        if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
-            try!(write!(f, "]"));
-        }
-        Ok(())
-    }
-}
-#[cfg(not(stage0))]
-impl<T: String> String for [T] {
-    fn fmt(&self, f: &mut Formatter) -> Result {
-        if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
-            try!(write!(f, "["));
-        }
-        let mut is_first = true;
-        for x in self.iter() {
-            if is_first {
-                is_first = false;
-            } else {
-                try!(write!(f, ", "));
-            }
-            try!(write!(f, "{}", *x))
-        }
-        if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 {
-            try!(write!(f, "]"));
-        }
-        Ok(())
-    }
-}
-
 impl Show for () {
     fn fmt(&self, f: &mut Formatter) -> Result {
         f.pad("()")
     }
 }
 
-impl String for () {
-    fn fmt(&self, f: &mut Formatter) -> Result {
-        f.pad("()")
-    }
-}
-
 impl<T: Copy + Show> Show for Cell<T> {
     fn fmt(&self, f: &mut Formatter) -> Result {
         write!(f, "Cell {{ value: {:?} }}", self.get())
@@ -946,6 +896,7 @@ fn fmt(&self, f: &mut Formatter) -> Result {
     }
 }
 
+#[stable]
 impl String for Utf8Error {
     fn fmt(&self, f: &mut Formatter) -> Result {
         match *self {
index 272570a0d5bb93e0e48256625bd4ed76400c88c4..56e27e801af9aed9159331715b93752c0db81311 100644 (file)
 
 use self::Option::*;
 
+use clone::Clone;
 use cmp::{Eq, Ord};
 use default::Default;
-use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator};
+use fmt;
 use iter::{ExactSizeIterator};
+use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator};
 use mem;
-use result::Result;
+use ops::{Deref, FnOnce};
 use result::Result::{Ok, Err};
-use slice;
+use result::Result;
 use slice::AsSlice;
-use clone::Clone;
-use ops::{Deref, FnOnce};
+use slice;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
 // `Iterator`, which is one. The compiler assumes that the `next` method of
@@ -762,7 +763,6 @@ fn as_slice<'a>(&'a self) -> &'a [T] {
 
 #[stable]
 impl<T> Default for Option<T> {
-    #[stable]
     #[inline]
     #[stable]
     fn default() -> Option<T> { None }
index b24e7a7a4cf81a06d6fb25572293a787c1c56b5f..a818c92241e6983ca40e2e7648ae939a03968ab5 100644 (file)
@@ -51,6 +51,8 @@
 pub struct WhereClause<'a>(pub &'a clean::Generics);
 /// Wrapper struct for emitting type parameter bounds.
 pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
+/// Wrapper struct for emitting a comma-separated list of items
+pub struct CommaSep<'a, T: 'a>(pub &'a [T]);
 
 impl VisSpace {
     pub fn get(&self) -> Option<ast::Visibility> {
@@ -64,6 +66,16 @@ pub fn get(&self) -> ast::Unsafety {
     }
 }
 
+impl<'a, T: fmt::String> fmt::String for CommaSep<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        for (i, item) in self.0.iter().enumerate() {
+            if i != 0 { try!(write!(f, ", ")); }
+            try!(write!(f, "{}", item));
+        }
+        Ok(())
+    }
+}
+
 //NOTE(stage0): remove impl after snapshot
 #[cfg(stage0)]
 impl<'a> fmt::Show for TyParamBounds<'a> {
@@ -530,7 +542,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                        lifetimes = if decl.lifetimes.len() == 0 {
                            "".to_string()
                        } else {
-                           format!("for &lt;{:#}&gt;", decl.lifetimes)
+                           format!("for &lt;{}&gt;",
+                                   CommaSep(decl.lifetimes.as_slice()))
                        },
                        args = decl.decl.inputs,
                        arrow = decl.decl.output,
@@ -562,7 +575,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                        lifetimes = if decl.lifetimes.len() == 0 {
                            "".to_string()
                        } else {
-                           format!("for &lt;{:#}&gt;", decl.lifetimes)
+                           format!("for &lt;{}&gt;",
+                                   CommaSep(decl.lifetimes.as_slice()))
                        },
                        args = decl.decl.inputs,
                        bounds = if decl.bounds.len() == 0 {
@@ -592,7 +606,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 primitive_link(f, clean::PrimitiveTuple,
                                match typs.as_slice() {
                                     [ref one] => format!("({},)", one),
-                                    many => format!("({:#})", many)
+                                    many => format!("({})",
+                                                    CommaSep(many.as_slice()))
                                }.as_slice())
             }
             clean::Vector(ref t) => {
index 0b7dc19fcab4e0be31d6d57be9c64db670368ef7..f7dcef52a5890da274bac60493b64be9fbb6bf33 100644 (file)
@@ -60,7 +60,7 @@ pub fn is_sep(c: char) -> bool {
 
 impl fmt::Show for Path {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "Path {{ {} }}", self.display())
+        fmt::Show::fmt(&self.display(), f)
     }
 }
 
index 5c4e7aa9ac27b6fe4b6224c53cdc433d487498fa..e32c67548fc7d403b46b06bfc3c82b231ca312ed 100644 (file)
@@ -87,7 +87,7 @@ pub struct Path {
 
 impl fmt::Show for Path {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "Path {{ {} }}", self.display())
+        fmt::Show::fmt(&self.display(), f)
     }
 }
 
index 10c63965a7bbb78c04d642b6403f99a8376978d4..d983c5d5087897a9b676aee43fa7350ebdfa8f82 100644 (file)
@@ -18,7 +18,7 @@ struct defer<'a> {
 impl<'a> Drop for defer<'a> {
     fn drop(&mut self) {
         unsafe {
-            println!("{}", self.x);
+            println!("{:?}", self.x);
         }
     }
 }
index 1cbd6292e9907713d4eaecbc7bad812fc56ee76e..d9d3d79b5af16e6db3148edac10ace30a56f411d 100644 (file)
@@ -15,5 +15,5 @@ fn read_lines_borrowed<'a>() -> Vec<&'a str> {
 }
 
 fn main() {
-    println!("{}", read_lines_borrowed());
+    println!("{:?}", read_lines_borrowed());
 }
index 9a09448ff01fed54bb8cbd0e862bdebbb542ce24..3d4d0fee0bfe26bc341b893fbc7d0fe89b8c2211 100644 (file)
@@ -23,5 +23,5 @@ fn main() {
 
     assert_eq!((*arc_v)[2], 3);
 
-    println!("{}", *arc_v);
+    println!("{:?}", *arc_v);
 }
index de23074368576d6476a48abad347d4076d03af13..02028fe62e5ebf2cd224776a5c9b55a8388efbb4 100644 (file)
@@ -21,5 +21,5 @@ fn main() {
 
     assert_eq!((*arc_v)[2], 3); //~ ERROR use of moved value: `arc_v`
 
-    println!("{}", *arc_v); //~ ERROR use of moved value: `arc_v`
+    println!("{:?}", *arc_v); //~ ERROR use of moved value: `arc_v`
 }
index 38177d076455d5bae99415e117762b32f291e42c..70c9d8351611ec8690459b074946a45a97c496d7 100644 (file)
@@ -34,6 +34,6 @@ fn main() {
     let foo = Foo { bar: [1u8, 2, 3, 4, 5], baz: 10i32 };
     unsafe {
         let oof: Oof<[u8; 5], i32> = mem::transmute(foo);
-        println!("{} {}", &oof.rab[], oof.zab);
+        println!("{:?} {:?}", &oof.rab[], oof.zab);
     }
 }
index ab6576b9b427d9921c25a5d1dabcc2f05c66865a..734ac3066534e3d00207730351c1d5333b3e0a90 100644 (file)
@@ -22,7 +22,7 @@ pub fn main() {
     let c : &[int] = &[2,2,2,2,3];
     let cc : &[int] = &[2,2,2,2,2,2];
 
-    println!("{}", a);
+    println!("{:?}", a);
 
     assert!(a < b);
     assert!(a <= b);
@@ -30,7 +30,7 @@ pub fn main() {
     assert!(b >= a);
     assert!(b > a);
 
-    println!("{}", b);
+    println!("{:?}", b);
 
     assert!(b < c);
     assert!(b <= c);
@@ -44,7 +44,7 @@ pub fn main() {
     assert!(c >= a);
     assert!(c > a);
 
-    println!("{}", c);
+    println!("{:?}", c);
 
     assert!(a < cc);
     assert!(a <= cc);
@@ -52,5 +52,5 @@ pub fn main() {
     assert!(cc >= a);
     assert!(cc > a);
 
-    println!("{}", cc);
+    println!("{:?}", cc);
 }
index 8b0d7c18fb119b6359ee2210fe2747f293985ef3..c8d1080372b504faf69473d793e84600024306bc 100644 (file)
@@ -183,7 +183,7 @@ fn test_write() {
 // can do with them just yet (to test the output)
 fn test_print() {
     print!("hi");
-    print!("{}", vec!(0u8));
+    print!("{:?}", vec!(0u8));
     println!("hello");
     println!("this is a {}", "test");
     println!("{foo}", foo="bar");
index 8acda1750069257f80cb09360568b269d451f7c2..fadc96f70baa347fdb3ba2551a57c7af445d59b2 100644 (file)
@@ -15,7 +15,7 @@ fn main() {
     let ss: &&[int] = &s;
     let sss: &&&[int] = &ss;
 
-    println!("{}", &s[0..3]);
-    println!("{}", &ss[3..]);
-    println!("{}", &sss[2..4]);
+    println!("{:?}", &s[0..3]);
+    println!("{:?}", &ss[3..]);
+    println!("{:?}", &sss[2..4]);
 }
index 7c8940aafbfbe82831d82363cc2a8f2ea8a8b315..cfe9c8f994c473bf056db18892bc8f6da2c25b83 100644 (file)
@@ -25,6 +25,6 @@ impl Copy for X {}
 
 pub fn main() {
     for &v in V.iter() {
-        println!("{}", v.vec);
+        println!("{:?}", v.vec);
     }
 }
index e854a7326329c8d6d0e977230224b3dc9285f578..b8cfccad081400872f676aa76c8217d21abc5cc8 100644 (file)
@@ -16,8 +16,8 @@ pub fn main() {
 
     print!("[");
     for xi in x.iter() {
-        print!("{}, ", &xi[]);
+        print!("{:?}, ", &xi[]);
     }
     println!("]");
-    println!("{}", &y[]);
+    println!("{:?}", &y[]);
 }
index 52e0ba89479f555340f95043ad9b916573f84a67..97c12d0954e4b6baf3314fc3c4098ccf7c456f80 100644 (file)
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 pub fn main() {
-    assert_eq!((vec!(0i, 1)).to_string(), "[0, 1]".to_string());
+    assert_eq!(format!("{:?}", vec!(0i, 1)), "[0i, 1i]".to_string());
 
     let foo = vec!(3i, 4);
     let bar: &[int] = &[4, 5];
 
-    assert_eq!(foo.to_string(), "[3, 4]".to_string());
-    assert_eq!(bar.to_string(), "[4, 5]".to_string());
+    assert_eq!(format!("{:?}", foo), "[3i, 4i]");
+    assert_eq!(format!("{:?}", bar), "[4i, 5i]");
 }