]> git.lizzy.rs Git - rust.git/commitdiff
Fix TryFrom for i128/u128
authorOliver Middleton <olliemail27@gmail.com>
Sat, 4 Feb 2017 23:10:28 +0000 (23:10 +0000)
committerOliver Middleton <olliemail27@gmail.com>
Sat, 4 Feb 2017 23:10:28 +0000 (23:10 +0000)
Another case of `as` cast silent truncation being error prone.

This also adds a few missing TryFrom tests to libcoretest.

src/libcore/num/mod.rs
src/libcoretest/num/mod.rs

index e907eae18bcbbca4d176639da26aa3eff86e3227..97ea6bb347b54adcecb766ba32169583baccf75e 100644 (file)
@@ -2626,8 +2626,8 @@ impl TryFrom<$unsigned> for $signed {
             type Err = TryFromIntError;
 
             fn try_from(u: $unsigned) -> Result<$signed, TryFromIntError> {
-                let max = <$signed as FromStrRadixHelper>::max_value() as u64;
-                if u as u64 > max {
+                let max = <$signed as FromStrRadixHelper>::max_value() as u128;
+                if u as u128 > max {
                     Err(TryFromIntError(()))
                 } else {
                     Ok(u as $signed)
@@ -2640,8 +2640,8 @@ impl TryFrom<$signed> for $unsigned {
             type Err = TryFromIntError;
 
             fn try_from(u: $signed) -> Result<$unsigned, TryFromIntError> {
-                let max = <$unsigned as FromStrRadixHelper>::max_value() as u64;
-                if u < 0 || u as u64 > max {
+                let max = <$unsigned as FromStrRadixHelper>::max_value() as u128;
+                if u < 0 || u as u128 > max {
                     Err(TryFromIntError(()))
                 } else {
                     Ok(u as $unsigned)
index 4834c0e072c9e412ae0da21751c3b1a73deb4f6d..51737c9c3b485e42b74b47e3671ee5eecc53a90d 100644 (file)
@@ -366,3 +366,35 @@ fn $fn_name() {
 test_impl_try_from_same_sign_err! { test_try_i64i8, i64, i8 }
 test_impl_try_from_same_sign_err! { test_try_i64i16, i64, i16 }
 test_impl_try_from_same_sign_err! { test_try_i64i32, i64, i32 }
+
+macro_rules! test_impl_try_from_signed_to_unsigned_err {
+    ($fn_name:ident, $source:ty, $target:ty) => {
+        #[test]
+        fn $fn_name() {
+            let max = <$source>::max_value();
+            let min = <$source>::min_value();
+            let zero: $source = 0;
+            let t_max = <$target>::max_value();
+            let t_min = <$target>::min_value();
+            assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
+            assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
+            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
+                       zero as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
+                            .unwrap(),
+                       t_max as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
+                            .unwrap(),
+                       t_min as $target);
+        }
+    }
+}
+
+test_impl_try_from_signed_to_unsigned_err! { test_try_i16u8, i16, u8 }
+
+test_impl_try_from_signed_to_unsigned_err! { test_try_i32u8, i32, u8 }
+test_impl_try_from_signed_to_unsigned_err! { test_try_i32u16, i32, u16 }
+
+test_impl_try_from_signed_to_unsigned_err! { test_try_i64u8, i64, u8 }
+test_impl_try_from_signed_to_unsigned_err! { test_try_i64u16, i64, u16 }
+test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }