From 23abb48e9b01d46dfefb278ae821de701586f79c Mon Sep 17 00:00:00 2001
From: Erick Tryzelaar <erick.tryzelaar@gmail.com>
Date: Sun, 22 Jun 2014 21:54:58 -0400
Subject: [PATCH] Simplify the Serializable typarams

This closes #14302
---
 bench_log.rs |  63 +++++++++++++++++-------
 json.rs      |  83 +++++++++++++++-----------------
 ser.rs       | 133 +++++++++++++++++++++++++++++----------------------
 3 files changed, 159 insertions(+), 120 deletions(-)

diff --git a/bench_log.rs b/bench_log.rs
index c99cb84d..bf13ec62 100644
--- a/bench_log.rs
+++ b/bench_log.rs
@@ -24,9 +24,12 @@ struct Http {
     request_uri: String,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Http {
+impl ser::Serializable for Http {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         try!(s.serialize_struct_start("Http", 9));
 
         try!(s.serialize_struct_sep("protocol"));
@@ -67,9 +70,12 @@ enum HttpProtocol {
     HTTP11,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for HttpProtocol {
+impl ser::Serializable for HttpProtocol {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_uint(*self as uint)
     }
 }
@@ -89,9 +95,12 @@ enum HttpMethod {
     PATCH,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for HttpMethod {
+impl ser::Serializable for HttpMethod {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_uint(*self as uint)
     }
 }
@@ -104,9 +113,12 @@ enum CacheStatus {
     Hit,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for CacheStatus {
+impl ser::Serializable for CacheStatus {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_uint(*self as uint)
     }
 }
@@ -119,9 +131,12 @@ struct Origin {
     protocol: OriginProtocol,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Origin {
+impl ser::Serializable for Origin {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         try!(s.serialize_struct_start("Http", 4));
 
         try!(s.serialize_struct_sep("ip"));
@@ -147,9 +162,12 @@ enum OriginProtocol {
     HTTPS,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for OriginProtocol {
+impl ser::Serializable for OriginProtocol {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_uint(*self as uint)
     }
 }
@@ -163,9 +181,12 @@ enum ZonePlan {
     ENT,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for ZonePlan {
+impl ser::Serializable for ZonePlan {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_uint(*self as uint)
     }
 }
@@ -430,9 +451,12 @@ enum Country {
 	ZW,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Country {
+impl ser::Serializable for Country {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_uint(*self as uint)
     }
 }
@@ -453,9 +477,12 @@ struct Log {
     ray_id: String,
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Log {
+impl ser::Serializable for Log {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         try!(s.serialize_struct_start("Log", 12));
 
         try!(s.serialize_struct_sep("timestamp"));
diff --git a/json.rs b/json.rs
index 64f9388b..1447c201 100644
--- a/json.rs
+++ b/json.rs
@@ -233,7 +233,6 @@ use std::collections::treemap;
 use std::fmt;
 use std::io::MemWriter;
 use std::io;
-use std::mem::transmute;
 use std::num;
 use std::str::ScalarValue;
 use std::str;
@@ -419,9 +418,12 @@ impl fmt::Show for Json {
     }
 }
 
-impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Json {
+impl ser::Serializable for Json {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: ser::Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         match *self {
             Null => {
                 ().serialize(s)
@@ -780,26 +782,17 @@ impl<'a> Serializer<'a> {
     }
 
     /// Encode the specified struct into a json [u8]
-    pub fn buf_encode<
-        'a,
-        T: ser::Serializable<Serializer<'a>, io::IoError>
-    >(value: &T) -> Vec<u8> {
-       //Serialize the object in a string using a writer
+    pub fn buf_encode<T: ser::Serializable>(value: &T) -> Vec<u8> {
         let mut wr = MemWriter::new();
-        // FIXME(14302) remove the transmute and unsafe block.
-        unsafe {
+        {
             let mut serializer = Serializer::new(&mut wr);
-            // MemWriter never Errs
-            let _ = value.serialize(transmute(&mut serializer));
+            value.serialize(&mut serializer).unwrap();
         }
         wr.unwrap()
     }
 
     /// Encode the specified struct into a json str
-    pub fn str_encode<
-        'a,
-        T: ser::Serializable<Serializer<'a>, io::IoError>
-    >(value: &T) -> Result<String, Vec<u8>> {
+    pub fn str_encode<T: ser::Serializable>(value: &T) -> Result<String, Vec<u8>> {
         let buf = Serializer::buf_encode(value);
         String::from_utf8(buf)
     }
@@ -958,7 +951,7 @@ impl<'a> ser::Serializer<io::IoError> for Serializer<'a> {
 
     #[inline]
     fn serialize_option<
-        T: Serializable<Serializer<'a>, io::IoError>
+        T: Serializable
     >(&mut self, v: &Option<T>) -> Result<(), io::IoError> {
         match *v {
             Some(ref v) => {
@@ -972,7 +965,7 @@ impl<'a> ser::Serializer<io::IoError> for Serializer<'a> {
 
     #[inline]
     fn serialize_seq<
-        T: Serializable<Serializer<'a>, io::IoError>,
+        T: Serializable,
         Iter: Iterator<T>
     >(&mut self, mut iter: Iter) -> Result<(), io::IoError> {
         try!(self.wr.write_str("["));
@@ -991,8 +984,8 @@ impl<'a> ser::Serializer<io::IoError> for Serializer<'a> {
 
     #[inline]
     fn serialize_map<
-        K: Serializable<Serializer<'a>, io::IoError>,
-        V: Serializable<Serializer<'a>, io::IoError>,
+        K: Serializable,
+        V: Serializable,
         Iter: Iterator<(K, V)>
     >(&mut self, mut iter: Iter) -> Result<(), io::IoError> {
         try!(self.wr.write_str("{"));
@@ -1031,23 +1024,17 @@ impl<'a> PrettySerializer<'a> {
     }
 
     /// Encode the specified struct into a json [u8]
-    pub fn buf_encode<
-        T: ser::Serializable<PrettySerializer<'a>, io::IoError>
-    >(value: &T) -> Vec<u8> {
+    pub fn buf_encode<T: ser::Serializable>(value: &T) -> Vec<u8> {
         let mut wr = MemWriter::new();
-        // FIXME(14302) remove the transmute and unsafe block.
-        unsafe {
+        {
             let mut serializer = PrettySerializer::new(&mut wr);
-            // MemWriter never Errs
-            let _ = value.serialize(transmute(&mut serializer));
+            value.serialize(&mut serializer).unwrap();
         }
         wr.unwrap()
     }
 
     /// Encode the specified struct into a json str
-    pub fn str_encode<
-        T: ser::Serializable<PrettySerializer<'a>, io::IoError>
-    >(value: &T) -> Result<String, Vec<u8>> {
+    pub fn str_encode<T: ser::Serializable>(value: &T) -> Result<String, Vec<u8>> {
         let buf = PrettySerializer::buf_encode(value);
         String::from_utf8(buf)
     }
@@ -1218,7 +1205,7 @@ impl<'a> ser::Serializer<io::IoError> for PrettySerializer<'a> {
 
     #[inline]
     fn serialize_option<
-        T: Serializable<PrettySerializer<'a>, io::IoError>
+        T: Serializable
     >(&mut self, v: &Option<T>) -> Result<(), io::IoError> {
         match *v {
             Some(ref v) => {
@@ -1232,7 +1219,7 @@ impl<'a> ser::Serializer<io::IoError> for PrettySerializer<'a> {
 
     #[inline]
     fn serialize_seq<
-        T: Serializable<PrettySerializer<'a>, io::IoError>,
+        T: Serializable,
         Iter: Iterator<T>
     >(&mut self, mut iter: Iter) -> Result<(), io::IoError> {
         try!(self.wr.write_str("["));
@@ -1248,8 +1235,8 @@ impl<'a> ser::Serializer<io::IoError> for PrettySerializer<'a> {
 
     #[inline]
     fn serialize_map<
-        K: Serializable<PrettySerializer<'a>, io::IoError>,
-        V: Serializable<PrettySerializer<'a>, io::IoError>,
+        K: Serializable,
+        V: Serializable,
         Iter: Iterator<(K, V)>
     >(&mut self, mut iter: Iter) -> Result<(), io::IoError> {
         try!(self.wr.write_str("{"));
@@ -2200,7 +2187,6 @@ impl<A:ToJson> ToJson for Option<A> {
 
 #[cfg(test)]
 mod tests {
-    use std::io;
     use std::fmt::Show;
     use std::collections::TreeMap;
 
@@ -2238,9 +2224,12 @@ mod tests {
         Frog(String, Vec<int>)
     }
 
-    impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Animal {
+    impl ser::Serializable for Animal {
         #[inline]
-        fn serialize(&self, s: &mut S) -> Result<(), E> {
+        fn serialize<
+            S: ser::Serializer<E>,
+            E
+        >(&self, s: &mut S) -> Result<(), E> {
             match *self {
                 Dog => {
                     try!(s.serialize_enum_start("Animal", "Dog", 0));
@@ -2313,9 +2302,12 @@ mod tests {
         c: Vec<String>,
     }
 
-    impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Inner {
+    impl ser::Serializable for Inner {
         #[inline]
-        fn serialize(&self, s: &mut S) -> Result<(), E> {
+        fn serialize<
+            S: ser::Serializer<E>,
+            E
+        >(&self, s: &mut S) -> Result<(), E> {
             try!(s.serialize_struct_start("Inner", 3));
 
             try!(s.serialize_struct_sep("a"));
@@ -2407,9 +2399,12 @@ mod tests {
         inner: Vec<Inner>,
     }
 
-    impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Outer {
+    impl ser::Serializable for Outer {
         #[inline]
-        fn serialize(&self, s: &mut S) -> Result<(), E> {
+        fn serialize<
+            S: ser::Serializer<E>,
+            E
+        >(&self, s: &mut S) -> Result<(), E> {
             try!(s.serialize_struct_start("Outer", 1));
 
             try!(s.serialize_struct_sep("inner"));
@@ -2476,8 +2471,7 @@ mod tests {
     }
 
     fn test_encode_ok<
-        'a,
-        T: PartialEq + Show + ToJson + ser::Serializable<Serializer<'a>, io::IoError>
+        T: PartialEq + Show + ToJson + ser::Serializable
     >(errors: &[(T, &str)]) {
         for &(ref value, out) in errors.iter() {
             let out = out.to_string();
@@ -2491,8 +2485,7 @@ mod tests {
     }
 
     fn test_pretty_encode_ok<
-        'a,
-        T: PartialEq + Show + ToJson + ser::Serializable<PrettySerializer<'a>, io::IoError>
+        T: PartialEq + Show + ToJson + ser::Serializable
     >(errors: &[(T, &str)]) {
         for &(ref value, out) in errors.iter() {
             let out = out.to_string();
diff --git a/ser.rs b/ser.rs
index a24f02e2..6ae9f944 100644
--- a/ser.rs
+++ b/ser.rs
@@ -87,35 +87,39 @@ pub trait Serializer<E> {
     fn serialize_enum_sep(&mut self) -> Result<(), E>;
     fn serialize_enum_end(&mut self) -> Result<(), E>;
 
-    fn serialize_option<
-        T: Serializable<Self, E>
-    >(&mut self, v: &Option<T>) -> Result<(), E>;
+    fn serialize_option<T: Serializable>(&mut self, v: &Option<T>) -> Result<(), E>;
 
     fn serialize_seq<
-        T: Serializable<Self, E>,
+        T: Serializable,
         Iter: Iterator<T>
     >(&mut self, iter: Iter) -> Result<(), E>;
 
     fn serialize_map<
-        K: Serializable<Self, E>,
-        V: Serializable<Self, E>,
+        K: Serializable,
+        V: Serializable,
         Iter: Iterator<(K, V)>
     >(&mut self, iter: Iter) -> Result<(), E>;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-pub trait Serializable<S: Serializer<E>, E> {
-    fn serialize(&self, s: &mut S) -> Result<(), E>;
+pub trait Serializable {
+    fn serialize<
+        S: Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E>;
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
 macro_rules! impl_serializable {
     ($ty:ty, $method:ident, $variant:expr) => {
-        impl<'a, S: Serializer<E>, E> Serializable<S, E> for $ty {
+        impl<'a> Serializable for $ty {
             #[inline]
-            fn serialize(&self, s: &mut S) -> Result<(), E> {
+            fn serialize<
+                S: Serializer<E>,
+                E
+            >(&self, s: &mut S) -> Result<(), E> {
                 s.$method($variant)
             }
         }
@@ -141,12 +145,13 @@ impl_serializable!(String, serialize_str, self.as_slice())
 
 impl<
     'a,
-    E,
-    S: Serializer<E>,
-    T: Serializable<S, E>
-> Serializable<S, E> for &'a T {
+    T: Serializable
+> Serializable for &'a T {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         (*self).serialize(s)
     }
 }
@@ -154,12 +159,13 @@ impl<
 //////////////////////////////////////////////////////////////////////////////
 
 impl<
-    E,
-    S: Serializer<E>,
-    T: Serializable<S, E>
-> Serializable<S, E> for Option<T> {
+    T: Serializable
+> Serializable for Option<T> {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_option(self)
     }
 }
@@ -167,12 +173,13 @@ impl<
 //////////////////////////////////////////////////////////////////////////////
 
 impl<
-    E,
-    S: Serializer<E>,
-    T: Serializable<S, E>
-> Serializable<S, E> for Vec<T> {
+    T: Serializable
+> Serializable for Vec<T> {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_seq(self.iter())
     }
 }
@@ -180,25 +187,27 @@ impl<
 //////////////////////////////////////////////////////////////////////////////
 
 impl<
-    E,
-    S: Serializer<E>,
-    K: Serializable<S, E> + Eq + Hash,
-    V: Serializable<S, E>
-> Serializable<S, E> for HashMap<K, V> {
+    K: Serializable + Eq + Hash,
+    V: Serializable
+> Serializable for HashMap<K, V> {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_map(self.iter())
     }
 }
 
 impl<
-    E,
-    S: Serializer<E>,
-    K: Serializable<S, E> + Ord,
-    V: Serializable<S, E>
-> Serializable<S, E> for TreeMap<K, V> {
+    K: Serializable + Ord,
+    V: Serializable
+> Serializable for TreeMap<K, V> {
     #[inline]
-    fn serialize(&self, s: &mut S) -> Result<(), E> {
+    fn serialize<
+        S: Serializer<E>,
+        E
+    >(&self, s: &mut S) -> Result<(), E> {
         s.serialize_map(self.iter())
     }
 }
@@ -211,25 +220,26 @@ macro_rules! peel {
 
 macro_rules! impl_serialize_tuple {
     () => {
-        impl<
-            E,
-            S: Serializer<E>
-        > Serializable<S, E> for () {
+        impl Serializable for () {
             #[inline]
-            fn serialize(&self, s: &mut S) -> Result<(), E> {
+            fn serialize<
+                S: Serializer<E>,
+                E
+            >(&self, s: &mut S) -> Result<(), E> {
                 s.serialize_null()
             }
         }
     };
     ( $($name:ident,)+ ) => {
         impl<
-            E,
-            S: Serializer<E>,
-            $($name:Serializable<S, E>),*
-        > Serializable<S, E> for ($($name,)*) {
+            $($name:Serializable),*
+        > Serializable for ($($name,)*) {
             #[inline]
             #[allow(uppercase_variables)]
-            fn serialize(&self, s: &mut S) -> Result<(), E> {
+            fn serialize<
+                S: Serializer<E>,
+                E
+            >(&self, s: &mut S) -> Result<(), E> {
                 // FIXME: how can we count macro args?
                 let mut len = 0;
                 $({ let $name = 1; len += $name; })*;
@@ -269,9 +279,12 @@ mod tests {
         c: HashMap<String, Option<char>>,
     }
 
-    impl<S: Serializer<E>, E> Serializable<S, E> for Inner {
+    impl Serializable for Inner {
         #[inline]
-        fn serialize(&self, s: &mut S) -> Result<(), E> {
+        fn serialize<
+            S: Serializer<E>,
+            E
+        >(&self, s: &mut S) -> Result<(), E> {
             try!(s.serialize_struct_start("Inner", 3));
 
             try!(s.serialize_struct_sep("a"));
@@ -294,9 +307,12 @@ mod tests {
         inner: Vec<Inner>,
     }
 
-    impl<S: Serializer<E>, E> Serializable<S, E> for Outer {
+    impl Serializable for Outer {
         #[inline]
-        fn serialize(&self, s: &mut S) -> Result<(), E> {
+        fn serialize<
+            S: Serializer<E>,
+            E
+        >(&self, s: &mut S) -> Result<(), E> {
             try!(s.serialize_struct_start("Outer", 1));
 
             try!(s.serialize_struct_sep("inner"));
@@ -314,9 +330,12 @@ mod tests {
         Frog(String, int)
     }
 
-    impl<S: Serializer<E>, E> Serializable<S, E> for Animal {
+    impl Serializable for Animal {
         #[inline]
-        fn serialize(&self, s: &mut S) -> Result<(), E> {
+        fn serialize<
+            S: Serializer<E>,
+            E
+        >(&self, s: &mut S) -> Result<(), E> {
             match *self {
                 Dog => {
                     try!(s.serialize_enum_start("Animal", "Dog", 0));
@@ -508,7 +527,7 @@ mod tests {
         }
 
         fn serialize_option<
-            T: Serializable<AssertSerializer<Iter>, Error>
+            T: Serializable
         >(&mut self, v: &Option<T>) -> Result<(), Error> {
             match *v {
                 Some(ref v) => {
@@ -522,7 +541,7 @@ mod tests {
         }
 
         fn serialize_seq<
-            T: Serializable<AssertSerializer<Iter>, Error>,
+            T: Serializable,
             SeqIter: Iterator<T>
         >(&mut self, mut iter: SeqIter) -> Result<(), Error> {
             let (len, _) = iter.size_hint();
@@ -534,8 +553,8 @@ mod tests {
         }
 
         fn serialize_map<
-            K: Serializable<AssertSerializer<Iter>, Error>,
-            V: Serializable<AssertSerializer<Iter>, Error>,
+            K: Serializable,
+            V: Serializable,
             MapIter: Iterator<(K, V)>
         >(&mut self, mut iter: MapIter) -> Result<(), Error> {
             let (len, _) = iter.size_hint();