]>
git.proxmox.com Git - rustc.git/blob - src/librustc_const_math/int.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use std
::cmp
::Ordering
;
12 use syntax
::attr
::IntType
;
13 use syntax
::ast
::{IntTy, UintTy}
;
19 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, Hash, Eq, PartialEq)]
34 pub use self::ConstInt
::*;
38 ($
($t
:ident $min
:ident $max
:ident
)*) => {
42 pub const $min
: u64 = ::std
::$t
::MIN
as u64;
44 pub const $max
: u64 = ::std
::$t
::MAX
as u64;
50 pub const $min
: i64 = ::std
::$t
::MIN
as i64;
52 pub const $max
: i64 = ::std
::$t
::MAX
as i64;
59 i8 I8MIN I8MAX
i16 I16MIN I16MAX
i32 I32MIN I32MAX
i64 I64MIN I64MAX
isize IMIN IMAX
60 u8 U8MIN U8MAX
u16 U16MIN U16MAX
u32 U32MIN U32MAX
u64 U64MIN U64MAX
usize UMIN UMAX
64 /// If either value is `Infer` or `InferSigned`, try to turn the value into the type of
65 /// the other value. If both values have no type, don't do anything
66 pub fn infer(self, other
: Self) -> Result
<(Self, Self), ConstMathErr
> {
67 let inferred
= match (self, other
) {
68 (InferSigned(_
), InferSigned(_
))
69 | (Infer(_
), Infer(_
)) => self, // no inference possible
70 // kindof wrong, you could have had values > I64MAX during computation of a
71 (Infer(a @
0...as_u64
::I64MAX
), InferSigned(_
)) => InferSigned(a
as i64),
72 (Infer(_
), InferSigned(_
)) => return Err(ConstMathErr
::NotInRange
),
74 | (_
, Infer(_
)) => return other
.infer(self).map(|(b
, a
)| (a
, b
)),
76 (Infer(a @
0...as_u64
::I8MAX
), I8(_
)) => I8(a
as i64 as i8),
77 (Infer(a @
0...as_u64
::I16MAX
), I16(_
)) => I16(a
as i64 as i16),
78 (Infer(a @
0...as_u64
::I32MAX
), I32(_
)) => I32(a
as i64 as i32),
79 (Infer(a @
0...as_u64
::I64MAX
), I64(_
)) => I64(a
as i64),
80 (Infer(a @
0...as_u64
::I32MAX
), Isize(Is32(_
))) => Isize(Is32(a
as i64 as i32)),
81 (Infer(a @
0...as_u64
::I64MAX
), Isize(Is64(_
))) => Isize(Is64(a
as i64)),
82 (Infer(a @
0...as_u64
::U8MAX
), U8(_
)) => U8(a
as u8),
83 (Infer(a @
0...as_u64
::U16MAX
), U16(_
)) => U16(a
as u16),
84 (Infer(a @
0...as_u64
::U32MAX
), U32(_
)) => U32(a
as u32),
85 (Infer(a
), U64(_
)) => U64(a
),
86 (Infer(a @
0...as_u64
::U32MAX
), Usize(Us32(_
))) => Usize(Us32(a
as u32)),
87 (Infer(a
), Usize(Us64(_
))) => Usize(Us64(a
)),
89 (Infer(_
), _
) => return Err(ConstMathErr
::NotInRange
),
91 (InferSigned(a @ as_i64
::I8MIN
...as_i64
::I8MAX
), I8(_
)) => I8(a
as i8),
92 (InferSigned(a @ as_i64
::I16MIN
...as_i64
::I16MAX
), I16(_
)) => I16(a
as i16),
93 (InferSigned(a @ as_i64
::I32MIN
...as_i64
::I32MAX
), I32(_
)) => I32(a
as i32),
94 (InferSigned(a
), I64(_
)) => I64(a
),
95 (InferSigned(a @ as_i64
::I32MIN
...as_i64
::I32MAX
), Isize(Is32(_
))) => {
98 (InferSigned(a
), Isize(Is64(_
))) => Isize(Is64(a
)),
99 (InferSigned(a @
0...as_i64
::U8MAX
), U8(_
)) => U8(a
as u8),
100 (InferSigned(a @
0...as_i64
::U16MAX
), U16(_
)) => U16(a
as u16),
101 (InferSigned(a @
0...as_i64
::U32MAX
), U32(_
)) => U32(a
as u32),
102 (InferSigned(a @
0...as_i64
::I64MAX
), U64(_
)) => U64(a
as u64),
103 (InferSigned(a @
0...as_i64
::U32MAX
), Usize(Us32(_
))) => Usize(Us32(a
as u32)),
104 (InferSigned(a @
0...as_i64
::I64MAX
), Usize(Us64(_
))) => Usize(Us64(a
as u64)),
105 (InferSigned(_
), _
) => return Err(ConstMathErr
::NotInRange
),
106 _
=> self, // already known types
108 Ok((inferred
, other
))
111 /// Turn this value into an `Infer` or an `InferSigned`
112 pub fn erase_type(self) -> Self {
114 Infer(i
) => Infer(i
),
115 InferSigned(i
) if i
< 0 => InferSigned(i
),
116 I8(i
) if i
< 0 => InferSigned(i
as i64),
117 I16(i
) if i
< 0 => InferSigned(i
as i64),
118 I32(i
) if i
< 0 => InferSigned(i
as i64),
119 I64(i
) if i
< 0 => InferSigned(i
as i64),
120 Isize(Is32(i
)) if i
< 0 => InferSigned(i
as i64),
121 Isize(Is64(i
)) if i
< 0 => InferSigned(i
as i64),
122 InferSigned(i
) => Infer(i
as u64),
123 I8(i
) => Infer(i
as u64),
124 I16(i
) => Infer(i
as u64),
125 I32(i
) => Infer(i
as u64),
126 I64(i
) => Infer(i
as u64),
127 Isize(Is32(i
)) => Infer(i
as u64),
128 Isize(Is64(i
)) => Infer(i
as u64),
129 U8(i
) => Infer(i
as u64),
130 U16(i
) => Infer(i
as u64),
131 U32(i
) => Infer(i
as u64),
132 U64(i
) => Infer(i
as u64),
133 Usize(Us32(i
)) => Infer(i
as u64),
134 Usize(Us64(i
)) => Infer(i
),
138 /// Description of the type, not the value
139 pub fn description(&self) -> &'
static str {
141 Infer(_
) => "not yet inferred integral",
142 InferSigned(_
) => "not yet inferred signed integral",
156 /// Erases the type and returns a u64.
157 /// This is not the same as `-5i8 as u64` but as `-5i8 as i64 as u64`
158 pub fn to_u64_unchecked(self) -> u64 {
159 match self.erase_type() {
160 ConstInt
::Infer(i
) => i
,
161 ConstInt
::InferSigned(i
) => i
as u64,
166 /// Converts the value to a `u32` if it's in the range 0...std::u32::MAX
167 pub fn to_u32(&self) -> Option
<u32> {
169 I8(v
) if v
>= 0 => Some(v
as u32),
170 I16(v
) if v
>= 0 => Some(v
as u32),
171 I32(v
) if v
>= 0 => Some(v
as u32),
174 | I64(v
) if v
>= 0 && v
<= ::std
::u32::MAX
as i64 => Some(v
as u32),
175 Isize(Is32(v
)) if v
>= 0 => Some(v
as u32),
176 U8(v
) => Some(v
as u32),
177 U16(v
) => Some(v
as u32),
181 | U64(v
) if v
<= ::std
::u32::MAX
as u64 => Some(v
as u32),
182 Usize(Us32(v
)) => Some(v
),
187 /// Converts the value to a `u64` if it's >= 0
188 pub fn to_u64(&self) -> Option
<u64> {
191 InferSigned(v
) if v
>= 0 => Some(v
as u64),
192 I8(v
) if v
>= 0 => Some(v
as u64),
193 I16(v
) if v
>= 0 => Some(v
as u64),
194 I32(v
) if v
>= 0 => Some(v
as u64),
195 I64(v
) if v
>= 0 => Some(v
as u64),
196 Isize(Is32(v
)) if v
>= 0 => Some(v
as u64),
197 Isize(Is64(v
)) if v
>= 0 => Some(v
as u64),
198 U8(v
) => Some(v
as u64),
199 U16(v
) => Some(v
as u64),
200 U32(v
) => Some(v
as u64),
202 Usize(Us32(v
)) => Some(v
as u64),
203 Usize(Us64(v
)) => Some(v
),
208 pub fn is_negative(&self) -> bool
{
214 Isize(Is32(v
)) => v
< 0,
215 Isize(Is64(v
)) => v
< 0,
216 InferSigned(v
) => v
< 0,
221 /// Compares the values if they are of the same type
222 pub fn try_cmp(self, rhs
: Self) -> Result
<::std
::cmp
::Ordering
, ConstMathErr
> {
223 match self.infer(rhs
)?
{
224 (I8(a
), I8(b
)) => Ok(a
.cmp(&b
)),
225 (I16(a
), I16(b
)) => Ok(a
.cmp(&b
)),
226 (I32(a
), I32(b
)) => Ok(a
.cmp(&b
)),
227 (I64(a
), I64(b
)) => Ok(a
.cmp(&b
)),
228 (Isize(Is32(a
)), Isize(Is32(b
))) => Ok(a
.cmp(&b
)),
229 (Isize(Is64(a
)), Isize(Is64(b
))) => Ok(a
.cmp(&b
)),
230 (U8(a
), U8(b
)) => Ok(a
.cmp(&b
)),
231 (U16(a
), U16(b
)) => Ok(a
.cmp(&b
)),
232 (U32(a
), U32(b
)) => Ok(a
.cmp(&b
)),
233 (U64(a
), U64(b
)) => Ok(a
.cmp(&b
)),
234 (Usize(Us32(a
)), Usize(Us32(b
))) => Ok(a
.cmp(&b
)),
235 (Usize(Us64(a
)), Usize(Us64(b
))) => Ok(a
.cmp(&b
)),
236 (Infer(a
), Infer(b
)) => Ok(a
.cmp(&b
)),
237 (InferSigned(a
), InferSigned(b
)) => Ok(a
.cmp(&b
)),
238 _
=> Err(CmpBetweenUnequalTypes
),
242 /// Adds 1 to the value and wraps around if the maximum for the type is reached
243 pub fn wrap_incr(self) -> Self {
245 ($e
:expr
) => { ($e).wrapping_add(1) }
248 ConstInt
::I8(i
) => ConstInt
::I8(add1
!(i
)),
249 ConstInt
::I16(i
) => ConstInt
::I16(add1
!(i
)),
250 ConstInt
::I32(i
) => ConstInt
::I32(add1
!(i
)),
251 ConstInt
::I64(i
) => ConstInt
::I64(add1
!(i
)),
252 ConstInt
::Isize(ConstIsize
::Is32(i
)) => ConstInt
::Isize(ConstIsize
::Is32(add1
!(i
))),
253 ConstInt
::Isize(ConstIsize
::Is64(i
)) => ConstInt
::Isize(ConstIsize
::Is64(add1
!(i
))),
254 ConstInt
::U8(i
) => ConstInt
::U8(add1
!(i
)),
255 ConstInt
::U16(i
) => ConstInt
::U16(add1
!(i
)),
256 ConstInt
::U32(i
) => ConstInt
::U32(add1
!(i
)),
257 ConstInt
::U64(i
) => ConstInt
::U64(add1
!(i
)),
258 ConstInt
::Usize(ConstUsize
::Us32(i
)) => ConstInt
::Usize(ConstUsize
::Us32(add1
!(i
))),
259 ConstInt
::Usize(ConstUsize
::Us64(i
)) => ConstInt
::Usize(ConstUsize
::Us64(add1
!(i
))),
260 ConstInt
::Infer(_
) | ConstInt
::InferSigned(_
) => panic
!("no type info for const int"),
264 pub fn int_type(self) -> Option
<IntType
> {
266 ConstInt
::I8(_
) => Some(IntType
::SignedInt(IntTy
::I8
)),
267 ConstInt
::I16(_
) => Some(IntType
::SignedInt(IntTy
::I16
)),
268 ConstInt
::I32(_
) => Some(IntType
::SignedInt(IntTy
::I32
)),
269 ConstInt
::I64(_
) => Some(IntType
::SignedInt(IntTy
::I64
)),
270 ConstInt
::Isize(_
) => Some(IntType
::SignedInt(IntTy
::Is
)),
271 ConstInt
::U8(_
) => Some(IntType
::UnsignedInt(UintTy
::U8
)),
272 ConstInt
::U16(_
) => Some(IntType
::UnsignedInt(UintTy
::U16
)),
273 ConstInt
::U32(_
) => Some(IntType
::UnsignedInt(UintTy
::U32
)),
274 ConstInt
::U64(_
) => Some(IntType
::UnsignedInt(UintTy
::U64
)),
275 ConstInt
::Usize(_
) => Some(IntType
::UnsignedInt(UintTy
::Us
)),
281 impl ::std
::cmp
::PartialOrd
for ConstInt
{
282 fn partial_cmp(&self, other
: &Self) -> Option
<Ordering
> {
283 self.try_cmp(*other
).ok()
287 impl ::std
::cmp
::Ord
for ConstInt
{
288 fn cmp(&self, other
: &Self) -> Ordering
{
289 self.try_cmp(*other
).unwrap()
293 impl ::std
::fmt
::Display
for ConstInt
{
294 fn fmt(&self, fmt
: &mut ::std
::fmt
::Formatter
) -> Result
<(), ::std
::fmt
::Error
> {
296 Infer(i
) => write
!(fmt
, "{}", i
),
297 InferSigned(i
) => write
!(fmt
, "{}", i
),
298 I8(i
) => write
!(fmt
, "{}i8", i
),
299 I16(i
) => write
!(fmt
, "{}i16", i
),
300 I32(i
) => write
!(fmt
, "{}i32", i
),
301 I64(i
) => write
!(fmt
, "{}i64", i
),
302 Isize(ConstIsize
::Is64(i
)) => write
!(fmt
, "{}isize", i
),
303 Isize(ConstIsize
::Is32(i
)) => write
!(fmt
, "{}isize", i
),
304 U8(i
) => write
!(fmt
, "{}u8", i
),
305 U16(i
) => write
!(fmt
, "{}u16", i
),
306 U32(i
) => write
!(fmt
, "{}u32", i
),
307 U64(i
) => write
!(fmt
, "{}u64", i
),
308 Usize(ConstUsize
::Us64(i
)) => write
!(fmt
, "{}usize", i
),
309 Usize(ConstUsize
::Us32(i
)) => write
!(fmt
, "{}usize", i
),
314 macro_rules
! overflowing
{
315 ($e
:expr
, $err
:expr
) => {{
317 return Err(Overflow($err
));
324 macro_rules
! impl_binop
{
325 ($op
:ident
, $func
:ident
, $checked_func
:ident
) => {
326 impl ::std
::ops
::$op
for ConstInt
{
327 type Output
= Result
<Self, ConstMathErr
>;
328 fn $
func(self, rhs
: Self) -> Result
<Self, ConstMathErr
> {
329 match self.infer(rhs
)?
{
330 (I8(a
), I8(b
)) => a
.$
checked_func(b
).map(I8
),
331 (I16(a
), I16(b
)) => a
.$
checked_func(b
).map(I16
),
332 (I32(a
), I32(b
)) => a
.$
checked_func(b
).map(I32
),
333 (I64(a
), I64(b
)) => a
.$
checked_func(b
).map(I64
),
334 (Isize(Is32(a
)), Isize(Is32(b
))) => a
.$
checked_func(b
).map(Is32
).map(Isize
),
335 (Isize(Is64(a
)), Isize(Is64(b
))) => a
.$
checked_func(b
).map(Is64
).map(Isize
),
336 (U8(a
), U8(b
)) => a
.$
checked_func(b
).map(U8
),
337 (U16(a
), U16(b
)) => a
.$
checked_func(b
).map(U16
),
338 (U32(a
), U32(b
)) => a
.$
checked_func(b
).map(U32
),
339 (U64(a
), U64(b
)) => a
.$
checked_func(b
).map(U64
),
340 (Usize(Us32(a
)), Usize(Us32(b
))) => a
.$
checked_func(b
).map(Us32
).map(Usize
),
341 (Usize(Us64(a
)), Usize(Us64(b
))) => a
.$
checked_func(b
).map(Us64
).map(Usize
),
342 (Infer(a
), Infer(b
)) => a
.$
checked_func(b
).map(Infer
),
343 (InferSigned(a
), InferSigned(b
)) => a
.$
checked_func(b
).map(InferSigned
),
344 _
=> return Err(UnequalTypes(Op
::$op
)),
345 }.ok_or(Overflow(Op
::$op
))
351 macro_rules
! derive_binop
{
352 ($op
:ident
, $func
:ident
) => {
353 impl ::std
::ops
::$op
for ConstInt
{
354 type Output
= Result
<Self, ConstMathErr
>;
355 fn $
func(self, rhs
: Self) -> Result
<Self, ConstMathErr
> {
356 match self.infer(rhs
)?
{
357 (I8(a
), I8(b
)) => Ok(I8(a
.$
func(b
))),
358 (I16(a
), I16(b
)) => Ok(I16(a
.$
func(b
))),
359 (I32(a
), I32(b
)) => Ok(I32(a
.$
func(b
))),
360 (I64(a
), I64(b
)) => Ok(I64(a
.$
func(b
))),
361 (Isize(Is32(a
)), Isize(Is32(b
))) => Ok(Isize(Is32(a
.$
func(b
)))),
362 (Isize(Is64(a
)), Isize(Is64(b
))) => Ok(Isize(Is64(a
.$
func(b
)))),
363 (U8(a
), U8(b
)) => Ok(U8(a
.$
func(b
))),
364 (U16(a
), U16(b
)) => Ok(U16(a
.$
func(b
))),
365 (U32(a
), U32(b
)) => Ok(U32(a
.$
func(b
))),
366 (U64(a
), U64(b
)) => Ok(U64(a
.$
func(b
))),
367 (Usize(Us32(a
)), Usize(Us32(b
))) => Ok(Usize(Us32(a
.$
func(b
)))),
368 (Usize(Us64(a
)), Usize(Us64(b
))) => Ok(Usize(Us64(a
.$
func(b
)))),
369 (Infer(a
), Infer(b
)) => Ok(Infer(a
.$
func(b
))),
370 (InferSigned(a
), InferSigned(b
)) => Ok(InferSigned(a
.$
func(b
))),
371 _
=> Err(UnequalTypes(Op
::$op
)),
378 impl_binop
!(Add
, add
, checked_add
);
379 impl_binop
!(Sub
, sub
, checked_sub
);
380 impl_binop
!(Mul
, mul
, checked_mul
);
381 derive_binop
!(BitAnd
, bitand
);
382 derive_binop
!(BitOr
, bitor
);
383 derive_binop
!(BitXor
, bitxor
);
390 ) -> Result
<(), ConstMathErr
> {
392 (I8(_
), I8(0)) => Err(zerr
),
393 (I16(_
), I16(0)) => Err(zerr
),
394 (I32(_
), I32(0)) => Err(zerr
),
395 (I64(_
), I64(0)) => Err(zerr
),
396 (Isize(_
), Isize(Is32(0))) => Err(zerr
),
397 (Isize(_
), Isize(Is64(0))) => Err(zerr
),
398 (InferSigned(_
), InferSigned(0)) => Err(zerr
),
400 (U8(_
), U8(0)) => Err(zerr
),
401 (U16(_
), U16(0)) => Err(zerr
),
402 (U32(_
), U32(0)) => Err(zerr
),
403 (U64(_
), U64(0)) => Err(zerr
),
404 (Usize(_
), Usize(Us32(0))) => Err(zerr
),
405 (Usize(_
), Usize(Us64(0))) => Err(zerr
),
406 (Infer(_
), Infer(0)) => Err(zerr
),
408 (I8(::std
::i8::MIN
), I8(-1)) => Err(Overflow(op
)),
409 (I16(::std
::i16::MIN
), I16(-1)) => Err(Overflow(op
)),
410 (I32(::std
::i32::MIN
), I32(-1)) => Err(Overflow(op
)),
411 (I64(::std
::i64::MIN
), I64(-1)) => Err(Overflow(op
)),
412 (Isize(Is32(::std
::i32::MIN
)), Isize(Is32(-1))) => Err(Overflow(op
)),
413 (Isize(Is64(::std
::i64::MIN
)), Isize(Is64(-1))) => Err(Overflow(op
)),
414 (InferSigned(::std
::i64::MIN
), InferSigned(-1)) => Err(Overflow(op
)),
420 impl ::std
::ops
::Div
for ConstInt
{
421 type Output
= Result
<Self, ConstMathErr
>;
422 fn div(self, rhs
: Self) -> Result
<Self, ConstMathErr
> {
423 let (lhs
, rhs
) = self.infer(rhs
)?
;
424 check_division(lhs
, rhs
, Op
::Div
, DivisionByZero
)?
;
426 (I8(a
), I8(b
)) => Ok(I8(a
/b
)),
427 (I16(a
), I16(b
)) => Ok(I16(a
/b
)),
428 (I32(a
), I32(b
)) => Ok(I32(a
/b
)),
429 (I64(a
), I64(b
)) => Ok(I64(a
/b
)),
430 (Isize(Is32(a
)), Isize(Is32(b
))) => Ok(Isize(Is32(a
/b
))),
431 (Isize(Is64(a
)), Isize(Is64(b
))) => Ok(Isize(Is64(a
/b
))),
432 (InferSigned(a
), InferSigned(b
)) => Ok(InferSigned(a
/b
)),
434 (U8(a
), U8(b
)) => Ok(U8(a
/b
)),
435 (U16(a
), U16(b
)) => Ok(U16(a
/b
)),
436 (U32(a
), U32(b
)) => Ok(U32(a
/b
)),
437 (U64(a
), U64(b
)) => Ok(U64(a
/b
)),
438 (Usize(Us32(a
)), Usize(Us32(b
))) => Ok(Usize(Us32(a
/b
))),
439 (Usize(Us64(a
)), Usize(Us64(b
))) => Ok(Usize(Us64(a
/b
))),
440 (Infer(a
), Infer(b
)) => Ok(Infer(a
/b
)),
442 _
=> Err(UnequalTypes(Op
::Div
)),
447 impl ::std
::ops
::Rem
for ConstInt
{
448 type Output
= Result
<Self, ConstMathErr
>;
449 fn rem(self, rhs
: Self) -> Result
<Self, ConstMathErr
> {
450 let (lhs
, rhs
) = self.infer(rhs
)?
;
451 // should INT_MIN%-1 be zero or an error?
452 check_division(lhs
, rhs
, Op
::Rem
, RemainderByZero
)?
;
454 (I8(a
), I8(b
)) => Ok(I8(a
%b
)),
455 (I16(a
), I16(b
)) => Ok(I16(a
%b
)),
456 (I32(a
), I32(b
)) => Ok(I32(a
%b
)),
457 (I64(a
), I64(b
)) => Ok(I64(a
%b
)),
458 (Isize(Is32(a
)), Isize(Is32(b
))) => Ok(Isize(Is32(a
%b
))),
459 (Isize(Is64(a
)), Isize(Is64(b
))) => Ok(Isize(Is64(a
%b
))),
460 (InferSigned(a
), InferSigned(b
)) => Ok(InferSigned(a
%b
)),
462 (U8(a
), U8(b
)) => Ok(U8(a
%b
)),
463 (U16(a
), U16(b
)) => Ok(U16(a
%b
)),
464 (U32(a
), U32(b
)) => Ok(U32(a
%b
)),
465 (U64(a
), U64(b
)) => Ok(U64(a
%b
)),
466 (Usize(Us32(a
)), Usize(Us32(b
))) => Ok(Usize(Us32(a
%b
))),
467 (Usize(Us64(a
)), Usize(Us64(b
))) => Ok(Usize(Us64(a
%b
))),
468 (Infer(a
), Infer(b
)) => Ok(Infer(a
%b
)),
470 _
=> Err(UnequalTypes(Op
::Rem
)),
475 impl ::std
::ops
::Shl
<ConstInt
> for ConstInt
{
476 type Output
= Result
<Self, ConstMathErr
>;
477 fn shl(self, rhs
: Self) -> Result
<Self, ConstMathErr
> {
478 let b
= rhs
.to_u32().ok_or(ShiftNegative
)?
;
480 I8(a
) => Ok(I8(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
481 I16(a
) => Ok(I16(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
482 I32(a
) => Ok(I32(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
483 I64(a
) => Ok(I64(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
484 Isize(Is32(a
)) => Ok(Isize(Is32(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
)))),
485 Isize(Is64(a
)) => Ok(Isize(Is64(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
)))),
486 U8(a
) => Ok(U8(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
487 U16(a
) => Ok(U16(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
488 U32(a
) => Ok(U32(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
489 U64(a
) => Ok(U64(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
490 Usize(Us32(a
)) => Ok(Usize(Us32(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
)))),
491 Usize(Us64(a
)) => Ok(Usize(Us64(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
)))),
492 Infer(a
) => Ok(Infer(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
493 InferSigned(a
) => Ok(InferSigned(overflowing
!(a
.overflowing_shl(b
), Op
::Shl
))),
498 impl ::std
::ops
::Shr
<ConstInt
> for ConstInt
{
499 type Output
= Result
<Self, ConstMathErr
>;
500 fn shr(self, rhs
: Self) -> Result
<Self, ConstMathErr
> {
501 let b
= rhs
.to_u32().ok_or(ShiftNegative
)?
;
503 I8(a
) => Ok(I8(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
504 I16(a
) => Ok(I16(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
505 I32(a
) => Ok(I32(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
506 I64(a
) => Ok(I64(overflowing
!(a
.overflowing_shr(b
), Op
::Shl
))),
507 Isize(Is32(a
)) => Ok(Isize(Is32(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
)))),
508 Isize(Is64(a
)) => Ok(Isize(Is64(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
)))),
509 U8(a
) => Ok(U8(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
510 U16(a
) => Ok(U16(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
511 U32(a
) => Ok(U32(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
512 U64(a
) => Ok(U64(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
513 Usize(Us32(a
)) => Ok(Usize(Us32(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
)))),
514 Usize(Us64(a
)) => Ok(Usize(Us64(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
)))),
515 Infer(a
) => Ok(Infer(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
516 InferSigned(a
) => Ok(InferSigned(overflowing
!(a
.overflowing_shr(b
), Op
::Shr
))),
521 impl ::std
::ops
::Neg
for ConstInt
{
522 type Output
= Result
<Self, ConstMathErr
>;
523 fn neg(self) -> Result
<Self, ConstMathErr
> {
525 I8(a
) => Ok(I8(overflowing
!(a
.overflowing_neg(), Op
::Neg
))),
526 I16(a
) => Ok(I16(overflowing
!(a
.overflowing_neg(), Op
::Neg
))),
527 I32(a
) => Ok(I32(overflowing
!(a
.overflowing_neg(), Op
::Neg
))),
528 I64(a
) => Ok(I64(overflowing
!(a
.overflowing_neg(), Op
::Neg
))),
529 Isize(Is32(a
)) => Ok(Isize(Is32(overflowing
!(a
.overflowing_neg(), Op
::Neg
)))),
530 Isize(Is64(a
)) => Ok(Isize(Is64(overflowing
!(a
.overflowing_neg(), Op
::Neg
)))),
532 U16(0) => Ok(U16(0)),
533 U32(0) => Ok(U32(0)),
534 U64(0) => Ok(U64(0)),
535 Usize(Us32(0)) => Ok(Usize(Us32(0))),
536 Usize(Us64(0)) => Ok(Usize(Us64(0))),
537 U8(_
) => Err(UnsignedNegation
),
538 U16(_
) => Err(UnsignedNegation
),
539 U32(_
) => Err(UnsignedNegation
),
540 U64(_
) => Err(UnsignedNegation
),
541 Usize(_
) => Err(UnsignedNegation
),
542 Infer(a @
0...as_u64
::I64MAX
) => Ok(InferSigned(-(a
as i64))),
543 Infer(_
) => Err(Overflow(Op
::Neg
)),
544 InferSigned(a
) => Ok(InferSigned(overflowing
!(a
.overflowing_neg(), Op
::Neg
))),
549 impl ::std
::ops
::Not
for ConstInt
{
550 type Output
= Result
<Self, ConstMathErr
>;
551 fn not(self) -> Result
<Self, ConstMathErr
> {
554 I16(a
) => Ok(I16(!a
)),
555 I32(a
) => Ok(I32(!a
)),
556 I64(a
) => Ok(I64(!a
)),
557 Isize(Is32(a
)) => Ok(Isize(Is32(!a
))),
558 Isize(Is64(a
)) => Ok(Isize(Is64(!a
))),
560 U16(a
) => Ok(U16(!a
)),
561 U32(a
) => Ok(U32(!a
)),
562 U64(a
) => Ok(U64(!a
)),
563 Usize(Us32(a
)) => Ok(Usize(Us32(!a
))),
564 Usize(Us64(a
)) => Ok(Usize(Us64(!a
))),
565 Infer(a
) => Ok(Infer(!a
)),
566 InferSigned(a
) => Ok(InferSigned(!a
)),