]> git.lizzy.rs Git - rust.git/commitdiff
In the middle of the implementation
authorNicholas Mazzuca <npmazzuca@gmail.com>
Fri, 1 Jan 2016 12:28:26 +0000 (04:28 -0800)
committerNicholas Mazzuca <npmazzuca@gmail.com>
Fri, 1 Jan 2016 12:28:26 +0000 (04:28 -0800)
src/libcore/num/wrapping.rs
src/librand/isaac.rs
src/test/run-pass/num-wrapping.rs [new file with mode: 0644]

index a7d5fcafd56039163fc409a56f50e7fedf736171..637e99672aecad5a7ae154da091ec69c3188603b 100644 (file)
 #![unstable(feature = "wrapping", reason = "may be removed or relocated",
             issue = "27755")]
 
-pub use intrinsics::{add_with_overflow, sub_with_overflow, mul_with_overflow};
+use intrinsics::{add_with_overflow, sub_with_overflow, mul_with_overflow};
 
 use super::Wrapping;
 
 use ops::*;
 
-use ::{i8,i16,i32,i64};
+use ::{i8, i16, i32, i64, isize};
 
 pub trait OverflowingOps {
     fn overflowing_add(self, rhs: Self) -> (Self, bool);
@@ -33,15 +33,71 @@ pub trait OverflowingOps {
     fn overflowing_shr(self, rhs: u32) -> (Self, bool);
 }
 
-macro_rules! sh_impl {
-    ($t:ty, $f:ty) => (
+macro_rules! sh_impl_signed {
+    ($t:ident, $f:ident) => (
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Shl<$f> for Wrapping<$t> {
             type Output = Wrapping<$t>;
 
             #[inline(always)]
             fn shl(self, other: $f) -> Wrapping<$t> {
-                Wrapping(self.0 << other)
+                if other < 0 {
+                    Wrapping(self.0 >> (-other & self::shift_max::$t as $f))
+                } else {
+                    Wrapping(self.0 << (other & self::shift_max::$t as $f))
+                }
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl ShlAssign<$f> for Wrapping<$t> {
+            #[inline(always)]
+            fn shl_assign(&mut self, other: $f) {
+                *self = *self << other;
+            }
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Shr<$f> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn shr(self, other: $f) -> Wrapping<$t> {
+                if other < 0 {
+                    Wrapping(self.0 << (-other & self::shift_max::$t as $f))
+                } else {
+                    Wrapping(self.0 >> (other & self::shift_max::$t as $f))
+                }
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl ShrAssign<$f> for Wrapping<$t> {
+            #[inline(always)]
+            fn shr_assign(&mut self, other: $f) {
+                *self = *self >> other;
+            }
+        }
+    )
+}
+
+macro_rules! sh_impl_unsigned {
+    ($t:ident, $f:ident) => (
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Shl<$f> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn shl(self, other: $f) -> Wrapping<$t> {
+                Wrapping(self.0 << (other & self::shift_max::$t as $f))
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl ShlAssign<$f> for Wrapping<$t> {
+            #[inline(always)]
+            fn shl_assign(&mut self, other: $f) {
+                *self = *self << other;
             }
         }
 
@@ -51,7 +107,15 @@ impl Shr<$f> for Wrapping<$t> {
 
             #[inline(always)]
             fn shr(self, other: $f) -> Wrapping<$t> {
-                Wrapping(self.0 >> other)
+                Wrapping(self.0 >> (other & self::shift_max::$t as $f))
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl ShrAssign<$f> for Wrapping<$t> {
+            #[inline(always)]
+            fn shr_assign(&mut self, other: $f) {
+                *self = *self >> other;
             }
         }
     )
@@ -59,18 +123,18 @@ fn shr(self, other: $f) -> Wrapping<$t> {
 
 // FIXME (#23545): uncomment the remaining impls
 macro_rules! sh_impl_all {
-    ($($t:ty)*) => ($(
-        // sh_impl! { $t, u8 }
-        // sh_impl! { $t, u16 }
-        // sh_impl! { $t, u32 }
-        // sh_impl! { $t, u64 }
-        sh_impl! { $t, usize }
-
-        // sh_impl! { $t, i8 }
-        // sh_impl! { $t, i16 }
-        // sh_impl! { $t, i32 }
-        // sh_impl! { $t, i64 }
-        // sh_impl! { $t, isize }
+    ($($t:ident)*) => ($(
+        sh_impl_unsigned! { $t, u8 }
+        sh_impl_unsigned! { $t, u16 }
+        sh_impl_unsigned! { $t, u32 }
+        sh_impl_unsigned! { $t, u64 }
+        sh_impl_unsigned! { $t, usize }
+
+        sh_impl_signed! { $t, i8 }
+        sh_impl_signed! { $t, i16 }
+        sh_impl_signed! { $t, i32 }
+        sh_impl_signed! { $t, i64 }
+        sh_impl_signed! { $t, isize }
     )*)
 }
 
@@ -88,6 +152,32 @@ fn add(self, other: Wrapping<$t>) -> Wrapping<$t> {
             }
         }
 
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl Add<$t> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn add(self, other: $t) -> Wrapping<$t> {
+                self + Wrapping(other)
+            }
+        }
+
+        #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
+        impl AddAssign for Wrapping<$t> {
+            #[inline(always)]
+            fn add_assign(&mut self, other: Wrapping<$t>) {
+                *self = *self + other;
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl AddAssign<$t> for Wrapping<$t> {
+            #[inline(always)]
+            fn add_assign(&mut self, other: $t) {
+                self.add_assign(Wrapping(other))
+            }
+        }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Sub for Wrapping<$t> {
             type Output = Wrapping<$t>;
@@ -98,6 +188,32 @@ fn sub(self, other: Wrapping<$t>) -> Wrapping<$t> {
             }
         }
 
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl Sub<$t> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn sub(self, other: $t) -> Wrapping<$t> {
+                self - Wrapping(other)
+            }
+        }
+
+        #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
+        impl SubAssign for Wrapping<$t> {
+            #[inline(always)]
+            fn sub_assign(&mut self, other: Wrapping<$t>) {
+                *self = *self - other;
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl SubAssign<$t> for Wrapping<$t> {
+            #[inline(always)]
+            fn sub_assign(&mut self, other: $t) {
+                self.sub_assign(Wrapping(other))
+            }
+        }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Mul for Wrapping<$t> {
             type Output = Wrapping<$t>;
@@ -108,6 +224,32 @@ fn mul(self, other: Wrapping<$t>) -> Wrapping<$t> {
             }
         }
 
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl Mul<$t> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn mul(self, other: $t) -> Wrapping<$t> {
+                self * Wrapping(other)
+            }
+        }
+
+        #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
+        impl MulAssign for Wrapping<$t> {
+            #[inline(always)]
+            fn mul_assign(&mut self, other: Wrapping<$t>) {
+                *self = *self * other;
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl MulAssign<$t> for Wrapping<$t> {
+            #[inline(always)]
+            fn mul_assign(&mut self, other: $t) {
+                self.mul_assign(Wrapping(other))
+            }
+        }
+
         #[stable(feature = "wrapping_div", since = "1.3.0")]
         impl Div for Wrapping<$t> {
             type Output = Wrapping<$t>;
@@ -118,6 +260,68 @@ fn div(self, other: Wrapping<$t>) -> Wrapping<$t> {
             }
         }
 
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl Div<$t> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn div(self, other: $t) -> Wrapping<$t> {
+                self / Wrapping(other)
+            }
+        }
+
+        #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
+        impl DivAssign for Wrapping<$t> {
+            #[inline(always)]
+            fn div_assign(&mut self, other: Wrapping<$t>) {
+                *self = *self / other;
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl DivAssign<$t> for Wrapping<$t> {
+            #[inline(always)]
+            fn div_assign(&mut self, other: $t) {
+                self.div_assign(Wrapping(other))
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl Rem for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn rem(self, other: Wrapping<$t>) -> Wrapping<$t> {
+                Wrapping(self.0.wrapping_rem(other.0))
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl Rem<$t> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn rem(self, other: $t) -> Wrapping<$t> {
+                self % Wrapping(other)
+            }
+        }
+
+        #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
+        impl RemAssign for Wrapping<$t> {
+            #[inline(always)]
+            fn rem_assign(&mut self, other: Wrapping<$t>) {
+                *self = *self % other;
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl RemAssign<$t> for Wrapping<$t> {
+            #[inline(always)]
+            fn rem_assign(&mut self, other: $t) {
+                self.rem_assign(Wrapping(other))
+            }
+        }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Not for Wrapping<$t> {
             type Output = Wrapping<$t>;
@@ -138,6 +342,32 @@ fn bitxor(self, other: Wrapping<$t>) -> Wrapping<$t> {
             }
         }
 
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl BitXor<$t> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn bitxor(self, other: $t) -> Wrapping<$t> {
+                self ^ Wrapping(other)
+            }
+        }
+
+        #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
+        impl BitXorAssign for Wrapping<$t> {
+            #[inline(always)]
+            fn bitxor_assign(&mut self, other: Wrapping<$t>) {
+                *self = *self ^ other;
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl BitXorAssign<$t> for Wrapping<$t> {
+            #[inline(always)]
+            fn bitxor_assign(&mut self, other: $t) {
+                self.bitxor_assign(Wrapping(other))
+            }
+        }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         impl BitOr for Wrapping<$t> {
             type Output = Wrapping<$t>;
@@ -148,6 +378,32 @@ fn bitor(self, other: Wrapping<$t>) -> Wrapping<$t> {
             }
         }
 
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl BitOr<$t> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn bitor(self, other: $t) -> Wrapping<$t> {
+                self | Wrapping(other)
+            }
+        }
+
+        #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
+        impl BitOrAssign for Wrapping<$t> {
+            #[inline(always)]
+            fn bitor_assign(&mut self, other: Wrapping<$t>) {
+                *self = *self | other;
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl BitOrAssign<$t> for Wrapping<$t> {
+            #[inline(always)]
+            fn bitor_assign(&mut self, other: $t) {
+                self.bitor_assign(Wrapping(other))
+            }
+        }
+
         #[stable(feature = "rust1", since = "1.0.0")]
         impl BitAnd for Wrapping<$t> {
             type Output = Wrapping<$t>;
@@ -157,6 +413,32 @@ fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> {
                 Wrapping(self.0 & other.0)
             }
         }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl BitAnd<$t> for Wrapping<$t> {
+            type Output = Wrapping<$t>;
+
+            #[inline(always)]
+            fn bitand(self, other: $t) -> Wrapping<$t> {
+                self & Wrapping(other)
+            }
+        }
+
+        #[unstable(feature = "op_assign_traits", reason = "recently added", issue = "28235")]
+        impl BitAndAssign for Wrapping<$t> {
+            #[inline(always)]
+            fn bitand_assign(&mut self, other: Wrapping<$t>) {
+                *self = *self & other;
+            }
+        }
+
+        #[unstable(feature = "wrapping_impls", reason = "recently added", issue = "30524")]
+        impl BitAndAssign<$t> for Wrapping<$t> {
+            #[inline(always)]
+            fn bitand_assign(&mut self, other: $t) {
+                self.bitand_assign(Wrapping(other))
+            }
+        }
     )*)
 }
 
@@ -165,15 +447,29 @@ fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> {
 mod shift_max {
     #![allow(non_upper_case_globals)]
 
+    #[cfg(target_pointer_width = "32")]
+    mod platform {
+        pub const usize: u32 = super::u32;
+        pub const isize: u32 = super::i32;
+    }
+
+    #[cfg(target_pointer_width = "64")]
+    mod platform {
+        pub const usize: u32 = super::u64;
+        pub const isize: u32 = super::i64;
+    }
+
     pub const  i8: u32 = (1 << 3) - 1;
     pub const i16: u32 = (1 << 4) - 1;
     pub const i32: u32 = (1 << 5) - 1;
     pub const i64: u32 = (1 << 6) - 1;
+    pub use self::platform::isize;
 
     pub const  u8: u32 = i8;
     pub const u16: u32 = i16;
     pub const u32: u32 = i32;
     pub const u64: u32 = i64;
+    pub use self::platform::usize;
 }
 
 macro_rules! signed_overflowing_impl {
@@ -288,193 +584,5 @@ fn overflowing_neg(self) -> ($t, bool) {
     )*)
 }
 
-signed_overflowing_impl! { i8 i16 i32 i64 }
-unsigned_overflowing_impl! { u8 u16 u32 u64 }
-
-#[cfg(target_pointer_width = "64")]
-impl OverflowingOps for usize {
-    #[inline(always)]
-    fn overflowing_add(self, rhs: usize) -> (usize, bool) {
-        unsafe {
-            add_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
-        unsafe {
-            sub_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
-        unsafe {
-            mul_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_div(self, rhs: usize) -> (usize, bool) {
-        let (r, f) = (self as u64).overflowing_div(rhs as u64);
-        (r as usize, f)
-    }
-    #[inline(always)]
-    fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
-        let (r, f) = (self as u64).overflowing_rem(rhs as u64);
-        (r as usize, f)
-    }
-    #[inline(always)]
-    fn overflowing_neg(self) -> (usize, bool) {
-        let (r, f) = (self as u64).overflowing_neg();
-        (r as usize, f)
-    }
-    #[inline(always)]
-    fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
-        let (r, f) = (self as u64).overflowing_shl(rhs);
-        (r as usize, f)
-    }
-    #[inline(always)]
-    fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
-        let (r, f) = (self as u64).overflowing_shr(rhs);
-        (r as usize, f)
-    }
-}
-
-#[cfg(target_pointer_width = "32")]
-impl OverflowingOps for usize {
-    #[inline(always)]
-    fn overflowing_add(self, rhs: usize) -> (usize, bool) {
-        unsafe {
-            add_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
-        unsafe {
-            sub_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
-        unsafe {
-            mul_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_div(self, rhs: usize) -> (usize, bool) {
-        let (r, f) = (self as u32).overflowing_div(rhs as u32);
-        (r as usize, f)
-    }
-    #[inline(always)]
-    fn overflowing_rem(self, rhs: usize) -> (usize, bool) {
-        let (r, f) = (self as u32).overflowing_rem(rhs as u32);
-        (r as usize, f)
-    }
-    #[inline(always)]
-    fn overflowing_neg(self) -> (usize, bool) {
-        let (r, f) = (self as u32).overflowing_neg();
-        (r as usize, f)
-    }
-    #[inline(always)]
-    fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
-        let (r, f) = (self as u32).overflowing_shl(rhs);
-        (r as usize, f)
-    }
-    #[inline(always)]
-    fn overflowing_shr(self, rhs: u32) -> (usize, bool) {
-        let (r, f) = (self as u32).overflowing_shr(rhs);
-        (r as usize, f)
-    }
-}
-
-#[cfg(target_pointer_width = "64")]
-impl OverflowingOps for isize {
-    #[inline(always)]
-    fn overflowing_add(self, rhs: isize) -> (isize, bool) {
-        unsafe {
-            add_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
-        unsafe {
-            sub_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
-        unsafe {
-            mul_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_div(self, rhs: isize) -> (isize, bool) {
-        let (r, f) = (self as i64).overflowing_div(rhs as i64);
-        (r as isize, f)
-    }
-    #[inline(always)]
-    fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
-        let (r, f) = (self as i64).overflowing_rem(rhs as i64);
-        (r as isize, f)
-    }
-    #[inline(always)]
-    fn overflowing_neg(self) -> (isize, bool) {
-        let (r, f) = (self as i64).overflowing_neg();
-        (r as isize, f)
-    }
-    #[inline(always)]
-    fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
-        let (r, f) = (self as i64).overflowing_shl(rhs);
-        (r as isize, f)
-    }
-    #[inline(always)]
-    fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
-        let (r, f) = (self as i64).overflowing_shr(rhs);
-        (r as isize, f)
-    }
-}
-
-#[cfg(target_pointer_width = "32")]
-impl OverflowingOps for isize {
-    #[inline(always)]
-    fn overflowing_add(self, rhs: isize) -> (isize, bool) {
-        unsafe {
-            add_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
-        unsafe {
-            sub_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
-        unsafe {
-            mul_with_overflow(self, rhs)
-        }
-    }
-    #[inline(always)]
-    fn overflowing_div(self, rhs: isize) -> (isize, bool) {
-        let (r, f) = (self as i32).overflowing_div(rhs as i32);
-        (r as isize, f)
-    }
-    #[inline(always)]
-    fn overflowing_rem(self, rhs: isize) -> (isize, bool) {
-        let (r, f) = (self as i32).overflowing_rem(rhs as i32);
-        (r as isize, f)
-    }
-    #[inline(always)]
-    fn overflowing_neg(self) -> (isize, bool) {
-        let (r, f) = (self as i32).overflowing_neg();
-        (r as isize, f)
-    }
-    #[inline(always)]
-    fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
-        let (r, f) = (self as i32).overflowing_shl(rhs);
-        (r as isize, f)
-    }
-    #[inline(always)]
-    fn overflowing_shr(self, rhs: u32) -> (isize, bool) {
-        let (r, f) = (self as i32).overflowing_shr(rhs);
-        (r as isize, f)
-    }
-}
+signed_overflowing_impl! { i8 i16 i32 i64 isize }
+unsigned_overflowing_impl! { u8 u16 u32 u64 usize }
index 28eff87bde3b762246e11abec3c6039d93c51b21..545fd22cc592960517e1ec0242b2010d048fedeb 100644 (file)
@@ -170,7 +170,7 @@ fn isaac(&mut self) {
         const MIDPOINT: usize = RAND_SIZE_USIZE / 2;
 
         macro_rules! ind {
-            ($x:expr) => (self.mem[($x >> 2).0 as usize & (RAND_SIZE_USIZE - 1)] )
+            ($x:expr) => (self.mem[($x >> 2u32).0 as usize & (RAND_SIZE_USIZE - 1)] )
         }
 
         let r = [(0, MIDPOINT), (MIDPOINT, 0)];
@@ -452,7 +452,7 @@ fn isaac64(&mut self) {
         const MP_VEC: [(usize, usize); 2] = [(0, MIDPOINT), (MIDPOINT, 0)];
         macro_rules! ind {
             ($x:expr) => {
-                *self.mem.get_unchecked((($x >> 3).0 as usize) & (RAND_SIZE_64 - 1))
+                *self.mem.get_unchecked((($x >> 3u32).0 as usize) & (RAND_SIZE_64 - 1))
             }
         }
 
@@ -495,10 +495,10 @@ macro_rules! rngstepn {
                     }}
                 }
 
-                rngstepp!(0, 21);
-                rngstepn!(1, 5);
-                rngstepp!(2, 12);
-                rngstepn!(3, 33);
+                rngstepp!(0, 21u32);
+                rngstepn!(1, 5u32);
+                rngstepp!(2, 12u32);
+                rngstepn!(3, 33u32);
             }
         }
 
diff --git a/src/test/run-pass/num-wrapping.rs b/src/test/run-pass/num-wrapping.rs
new file mode 100644 (file)
index 0000000..398b400
--- /dev/null
@@ -0,0 +1,405 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// compile-flags: -C debug-assertions
+//
+// Test std::num::Wrapping<T> for {uN, iN, usize, isize}
+
+#![feature(op_assign_traits, num_bits_bytes)]
+
+use std::num::Wrapping;
+use std::ops::{
+    Add, Sub, Mul, Div, Rem, BitXor, BitOr, BitAnd,
+    AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, BitXorAssign, BitOrAssign, BitAndAssign,
+    Shl, Shr, ShlAssign, ShrAssign
+};
+use std::{i8, i16, i32, i64, isize, u8, u16, u32, u64, usize};
+
+use std::test::black_box;
+
+fn main() {
+    test_ops();
+    test_op_assigns();
+    test_sh_ops();
+    test_sh_op_assigns();
+}
+
+fn test_ops() {
+    macro_rules! op_test {
+        ($op:ident ($lhs:expr, $rhs:expr) == $ans:expr) => {
+            assert_eq!(black_box(Wrapping($lhs).$op(Wrapping($rhs))), Wrapping($ans));
+            assert_eq!(black_box(Wrapping($lhs).$op($rhs)), Wrapping($ans));
+        }
+    }
+
+    op_test!(add(i8::MAX, 1) == i8::MIN);
+    op_test!(add(i16::MAX, 1) == i16::MIN);
+    op_test!(add(i32::MAX, 1) == i32::MIN);
+    op_test!(add(i64::MAX, 1) == i64::MIN);
+    op_test!(add(isize::MAX, 1) == isize::MIN);
+
+    op_test!(add(u8::MAX, 1) == 0);
+    op_test!(add(u16::MAX, 1) == 0);
+    op_test!(add(u32::MAX, 1) == 0);
+    op_test!(add(u64::MAX, 1) == 0);
+    op_test!(add(usize::MAX, 1) == 0);
+
+
+    op_test!(sub(i8::MIN, 1) == i8::MAX);
+    op_test!(sub(i16::MIN, 1) == i16::MAX);
+    op_test!(sub(i32::MIN, 1) == i32::MAX);
+    op_test!(sub(i64::MIN, 1) == i64::MAX);
+    op_test!(sub(isize::MIN, 1) == isize::MAX);
+
+    op_test!(sub(0u8, 1) == u8::MAX);
+    op_test!(sub(0u16, 1) == u16::MAX);
+    op_test!(sub(0u32, 1) == u32::MAX);
+    op_test!(sub(0u64, 1) == u64::MAX);
+    op_test!(sub(0usize, 1) == usize::MAX);
+
+
+    op_test!(mul(i8::MAX, 2) == -2);
+    op_test!(mul(i16::MAX, 2) == -2);
+    op_test!(mul(i32::MAX, 2) == -2);
+    op_test!(mul(i64::MAX, 2) == -2);
+    op_test!(mul(isize::MAX, 2) == -2);
+
+    op_test!(mul(u8::MAX, 2) == u8::MAX - 1);
+    op_test!(mul(u16::MAX, 2) == u16::MAX - 1);
+    op_test!(mul(u32::MAX, 2) == u32::MAX - 1);
+    op_test!(mul(u64::MAX, 2) == u64::MAX - 1);
+    op_test!(mul(usize::MAX, 2) == usize::MAX - 1);
+
+
+    op_test!(div(i8::MIN, -1) == i8::MIN);
+    op_test!(div(i16::MIN, -1) == i16::MIN);
+    op_test!(div(i32::MIN, -1) == i32::MIN);
+    op_test!(div(i64::MIN, -1) == i64::MIN);
+    op_test!(div(isize::MIN, -1) == isize::MIN);
+
+
+    op_test!(rem(i8::MIN, -1) == 0);
+    op_test!(rem(i16::MIN, -1) == 0);
+    op_test!(rem(i32::MIN, -1) == 0);
+    op_test!(rem(i64::MIN, -1) == 0);
+    op_test!(rem(isize::MIN, -1) == 0);
+
+    // these are not that interesting, just testing to make sure they are implemented correctly
+    op_test!(bitxor(0b101010i8, 0b100110) == 0b001100);
+    op_test!(bitxor(0b101010i16, 0b100110) == 0b001100);
+    op_test!(bitxor(0b101010i32, 0b100110) == 0b001100);
+    op_test!(bitxor(0b101010i64, 0b100110) == 0b001100);
+    op_test!(bitxor(0b101010isize, 0b100110) == 0b001100);
+
+    op_test!(bitxor(0b101010u8, 0b100110) == 0b001100);
+    op_test!(bitxor(0b101010u16, 0b100110) == 0b001100);
+    op_test!(bitxor(0b101010u32, 0b100110) == 0b001100);
+    op_test!(bitxor(0b101010u64, 0b100110) == 0b001100);
+    op_test!(bitxor(0b101010usize, 0b100110) == 0b001100);
+
+
+    op_test!(bitor(0b101010i8, 0b100110) == 0b101110);
+    op_test!(bitor(0b101010i16, 0b100110) == 0b101110);
+    op_test!(bitor(0b101010i32, 0b100110) == 0b101110);
+    op_test!(bitor(0b101010i64, 0b100110) == 0b101110);
+    op_test!(bitor(0b101010isize, 0b100110) == 0b101110);
+
+    op_test!(bitor(0b101010u8, 0b100110) == 0b101110);
+    op_test!(bitor(0b101010u16, 0b100110) == 0b101110);
+    op_test!(bitor(0b101010u32, 0b100110) == 0b101110);
+    op_test!(bitor(0b101010u64, 0b100110) == 0b101110);
+    op_test!(bitor(0b101010usize, 0b100110) == 0b101110);
+
+
+    op_test!(bitand(0b101010i8, 0b100110) == 0b100010);
+    op_test!(bitand(0b101010i16, 0b100110) == 0b100010);
+    op_test!(bitand(0b101010i32, 0b100110) == 0b100010);
+    op_test!(bitand(0b101010i64, 0b100110) == 0b100010);
+    op_test!(bitand(0b101010isize, 0b100110) == 0b100010);
+
+    op_test!(bitand(0b101010u8, 0b100110) == 0b100010);
+    op_test!(bitand(0b101010u16, 0b100110) == 0b100010);
+    op_test!(bitand(0b101010u32, 0b100110) == 0b100010);
+    op_test!(bitand(0b101010u64, 0b100110) == 0b100010);
+    op_test!(bitand(0b101010usize, 0b100110) == 0b100010);
+}
+
+fn test_op_assigns() {
+    macro_rules! op_assign_test {
+        ($op:ident ($initial:expr, $rhs:expr) == $ans:expr) => {
+            {
+                let mut tmp = Wrapping($initial);
+                tmp = black_box(tmp);
+                tmp.$op(Wrapping($rhs));
+                assert_eq!(black_box(tmp), Wrapping($ans));
+            }
+            {
+                let mut tmp = Wrapping($initial);
+                tmp = black_box(tmp);
+                tmp.$op($rhs);
+                assert_eq!(black_box(tmp), Wrapping($ans));
+            }
+        }
+    }
+    op_assign_test!(add_assign(i8::MAX, 1) == i8::MIN);
+    op_assign_test!(add_assign(i16::MAX, 1) == i16::MIN);
+    op_assign_test!(add_assign(i32::MAX, 1) == i32::MIN);
+    op_assign_test!(add_assign(i64::MAX, 1) == i64::MIN);
+    op_assign_test!(add_assign(isize::MAX, 1) == isize::MIN);
+
+    op_assign_test!(add_assign(u8::MAX, 1) == u8::MIN);
+    op_assign_test!(add_assign(u16::MAX, 1) == u16::MIN);
+    op_assign_test!(add_assign(u32::MAX, 1) == u32::MIN);
+    op_assign_test!(add_assign(u64::MAX, 1) == u64::MIN);
+    op_assign_test!(add_assign(usize::MAX, 1) == usize::MIN);
+
+
+    op_assign_test!(sub_assign(i8::MIN, 1) == i8::MAX);
+    op_assign_test!(sub_assign(i16::MIN, 1) == i16::MAX);
+    op_assign_test!(sub_assign(i32::MIN, 1) == i32::MAX);
+    op_assign_test!(sub_assign(i64::MIN, 1) == i64::MAX);
+    op_assign_test!(sub_assign(isize::MIN, 1) == isize::MAX);
+
+    op_assign_test!(sub_assign(u8::MIN, 1) == u8::MAX);
+    op_assign_test!(sub_assign(u16::MIN, 1) == u16::MAX);
+    op_assign_test!(sub_assign(u32::MIN, 1) == u32::MAX);
+    op_assign_test!(sub_assign(u64::MIN, 1) == u64::MAX);
+    op_assign_test!(sub_assign(usize::MIN, 1) == usize::MAX);
+
+
+    op_assign_test!(mul_assign(i8::MAX, 2) == -2);
+    op_assign_test!(mul_assign(i16::MAX, 2) == -2);
+    op_assign_test!(mul_assign(i32::MAX, 2) == -2);
+    op_assign_test!(mul_assign(i64::MAX, 2) == -2);
+    op_assign_test!(mul_assign(isize::MAX, 2) == -2);
+
+    op_assign_test!(mul_assign(u8::MAX, 2) == u8::MAX - 1);
+    op_assign_test!(mul_assign(u16::MAX, 2) == u16::MAX - 1);
+    op_assign_test!(mul_assign(u32::MAX, 2) == u32::MAX - 1);
+    op_assign_test!(mul_assign(u64::MAX, 2) == u64::MAX - 1);
+    op_assign_test!(mul_assign(usize::MAX, 2) == usize::MAX - 1);
+
+
+    op_assign_test!(div_assign(i8::MIN, -1) == i8::MIN);
+    op_assign_test!(div_assign(i16::MIN, -1) == i16::MIN);
+    op_assign_test!(div_assign(i32::MIN, -1) == i32::MIN);
+    op_assign_test!(div_assign(i64::MIN, -1) == i64::MIN);
+    op_assign_test!(div_assign(isize::MIN, -1) == isize::MIN);
+
+
+    op_assign_test!(rem_assign(i8::MIN, -1) == 0);
+    op_assign_test!(rem_assign(i16::MIN, -1) == 0);
+    op_assign_test!(rem_assign(i32::MIN, -1) == 0);
+    op_assign_test!(rem_assign(i64::MIN, -1) == 0);
+    op_assign_test!(rem_assign(isize::MIN, -1) == 0);
+
+
+    // these are not that interesting, just testing to make sure they are implemented correctly
+    op_assign_test!(bitxor_assign(0b101010i8, 0b100110) == 0b001100);
+    op_assign_test!(bitxor_assign(0b101010i16, 0b100110) == 0b001100);
+    op_assign_test!(bitxor_assign(0b101010i32, 0b100110) == 0b001100);
+    op_assign_test!(bitxor_assign(0b101010i64, 0b100110) == 0b001100);
+    op_assign_test!(bitxor_assign(0b101010isize, 0b100110) == 0b001100);
+
+    op_assign_test!(bitxor_assign(0b101010u8, 0b100110) == 0b001100);
+    op_assign_test!(bitxor_assign(0b101010u16, 0b100110) == 0b001100);
+    op_assign_test!(bitxor_assign(0b101010u32, 0b100110) == 0b001100);
+    op_assign_test!(bitxor_assign(0b101010u64, 0b100110) == 0b001100);
+    op_assign_test!(bitxor_assign(0b101010usize, 0b100110) == 0b001100);
+
+
+    op_assign_test!(bitor_assign(0b101010i8, 0b100110) == 0b101110);
+    op_assign_test!(bitor_assign(0b101010i16, 0b100110) == 0b101110);
+    op_assign_test!(bitor_assign(0b101010i32, 0b100110) == 0b101110);
+    op_assign_test!(bitor_assign(0b101010i64, 0b100110) == 0b101110);
+    op_assign_test!(bitor_assign(0b101010isize, 0b100110) == 0b101110);
+
+    op_assign_test!(bitor_assign(0b101010u8, 0b100110) == 0b101110);
+    op_assign_test!(bitor_assign(0b101010u16, 0b100110) == 0b101110);
+    op_assign_test!(bitor_assign(0b101010u32, 0b100110) == 0b101110);
+    op_assign_test!(bitor_assign(0b101010u64, 0b100110) == 0b101110);
+    op_assign_test!(bitor_assign(0b101010usize, 0b100110) == 0b101110);
+
+
+    op_assign_test!(bitand_assign(0b101010i8, 0b100110) == 0b100010);
+    op_assign_test!(bitand_assign(0b101010i16, 0b100110) == 0b100010);
+    op_assign_test!(bitand_assign(0b101010i32, 0b100110) == 0b100010);
+    op_assign_test!(bitand_assign(0b101010i64, 0b100110) == 0b100010);
+    op_assign_test!(bitand_assign(0b101010isize, 0b100110) == 0b100010);
+
+    op_assign_test!(bitand_assign(0b101010u8, 0b100110) == 0b100010);
+    op_assign_test!(bitand_assign(0b101010u16, 0b100110) == 0b100010);
+    op_assign_test!(bitand_assign(0b101010u32, 0b100110) == 0b100010);
+    op_assign_test!(bitand_assign(0b101010u64, 0b100110) == 0b100010);
+    op_assign_test!(bitand_assign(0b101010usize, 0b100110) == 0b100010);
+}
+
+fn test_sh_ops() {
+    macro_rules! sh_test {
+        ($op:ident ($lhs:expr, $rhs:expr) == $ans:expr) => {
+            assert_eq!(black_box(Wrapping($lhs).$op($rhs)), Wrapping($ans));
+        }
+    }
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as u8) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as u8) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as u8) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as u8) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as u8) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as i8) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as i8) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as i8) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as i8) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as i8) == usize::MAX - 1);
+
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as i16) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as i16) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as i16) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as i16) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as i16) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as i16) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as i16) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as i16) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as i16) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as i16) == usize::MAX - 1);
+
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as u16) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as u16) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as u16) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as u16) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as u16) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as u16) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as u16) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as u16) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as u16) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as u16) == usize::MAX - 1);
+
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as i32) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as i32) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as i32) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as i32) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as i32) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as i32) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as i32) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as i32) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as i32) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as i32) == usize::MAX - 1);
+
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as u32) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as u32) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as u32) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as u32) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as u32) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as u32) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as u32) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as u32) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as u32) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as u32) == usize::MAX - 1);
+
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as i64) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as i64) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as i64) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as i64) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as i64) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as i64) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as i64) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as i64) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as i64) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as i64) == usize::MAX - 1);
+
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as u64) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as u64) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as u64) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as u64) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as u64) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as u64) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as u64) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as u64) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as u64) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as u64) == usize::MAX - 1);
+
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as isize) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as isize) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as isize) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as isize) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as isize) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as isize) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as isize) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as isize) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as isize) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as isize) == usize::MAX - 1);
+
+    sh_test!(shl(i8::MAX, (i8::BITS + 1) as usize) == -2);
+    sh_test!(shl(i16::MAX, (i16::BITS + 1) as usize) == -2);
+    sh_test!(shl(i32::MAX, (i32::BITS + 1) as usize) == -2);
+    sh_test!(shl(i64::MAX, (i64::BITS + 1) as usize) == -2);
+    sh_test!(shl(isize::MAX, (isize::BITS + 1) as usize) == -2);
+
+    sh_test!(shl(u8::MAX, (u8::BITS + 1) as usize) == u8::MAX - 1);
+    sh_test!(shl(u16::MAX, (u16::BITS + 1) as usize) == u16::MAX - 1);
+    sh_test!(shl(u32::MAX, (u32::BITS + 1) as usize) == u32::MAX - 1);
+    sh_test!(shl(u64::MAX, (u64::BITS + 1) as usize) == u64::MAX - 1);
+    sh_test!(shl(usize::MAX, (usize::BITS + 1) as usize) == usize::MAX - 1);
+
+
+    sh_test!(shr(i8::MAX, i8::BITS + 1) == i8::MAX / 2);
+    sh_test!(shr(i16::MAX, i16::BITS + 1) == i16::MAX / 2);
+    sh_test!(shr(i32::MAX, i32::BITS + 1) == i32::MAX / 2);
+    sh_test!(shr(i64::MAX, i64::BITS + 1) == i64::MAX / 2);
+    sh_test!(shr(isize::MAX, isize::BITS + 1) == isize::MAX / 2);
+
+    sh_test!(shr(u8::MAX, u8::BITS + 1) == u8::MAX / 2);
+    sh_test!(shr(u16::MAX, u16::BITS + 1) == u16::MAX / 2);
+    sh_test!(shr(u32::MAX, u32::BITS + 1) == u32::MAX / 2);
+    sh_test!(shr(u64::MAX, u64::BITS + 1) == u64::MAX / 2);
+    sh_test!(shr(usize::MAX, usize::BITS + 1) == usize::MAX / 2);
+}
+
+fn test_sh_op_assigns() {
+    macro_rules! sh_assign_test {
+        ($op:ident ($initial:expr, $rhs:expr) == $ans:expr) => {{
+            let mut tmp = Wrapping($initial);
+            tmp = black_box(tmp);
+            tmp.$op($rhs);
+            assert_eq!(black_box(tmp), Wrapping($ans));
+        }}
+    }
+    sh_assign_test!(shl_assign(i8::MAX, i8::BITS + 1) == -2);
+    sh_assign_test!(shl_assign(i16::MAX, i16::BITS + 1) == -2);
+    sh_assign_test!(shl_assign(i32::MAX, i32::BITS + 1) == -2);
+    sh_assign_test!(shl_assign(i64::MAX, i64::BITS + 1) == -2);
+    sh_assign_test!(shl_assign(isize::MAX, isize::BITS + 1) == -2);
+
+    sh_assign_test!(shl_assign(u8::MAX, u8::BITS + 1) == u8::MAX - 1);
+    sh_assign_test!(shl_assign(u16::MAX, u16::BITS + 1) == u16::MAX - 1);
+    sh_assign_test!(shl_assign(u32::MAX, u32::BITS + 1) == u32::MAX - 1);
+    sh_assign_test!(shl_assign(u64::MAX, u64::BITS + 1) == u64::MAX - 1);
+    sh_assign_test!(shl_assign(usize::MAX, usize::BITS + 1) == usize::MAX - 1);
+
+
+    sh_assign_test!(shr_assign(i8::MAX, i8::BITS + 1) == i8::MAX / 2);
+    sh_assign_test!(shr_assign(i16::MAX, i16::BITS + 1) == i16::MAX / 2);
+    sh_assign_test!(shr_assign(i32::MAX, i32::BITS + 1) == i32::MAX / 2);
+    sh_assign_test!(shr_assign(i64::MAX, i64::BITS + 1) == i64::MAX / 2);
+    sh_assign_test!(shr_assign(isize::MAX, isize::BITS + 1) == isize::MAX / 2);
+
+    sh_assign_test!(shr_assign(u8::MAX, u8::BITS + 1) == u8::MAX / 2);
+    sh_assign_test!(shr_assign(u16::MAX, u16::BITS + 1) == u16::MAX / 2);
+    sh_assign_test!(shr_assign(u32::MAX, u32::BITS + 1) == u32::MAX / 2);
+    sh_assign_test!(shr_assign(u64::MAX, u64::BITS + 1) == u64::MAX / 2);
+    sh_assign_test!(shr_assign(usize::MAX, usize::BITS + 1) == usize::MAX / 2);
+}