1 use core::cmp::PartialEq;
2 use core::convert::{TryFrom, TryInto};
4 use core::marker::Copy;
5 use core::num::{can_not_overflow, IntErrorKind, ParseIntError, TryFromIntError};
6 use core::ops::{Add, Div, Mul, Rem, Sub};
7 use core::option::Option;
8 use core::option::Option::None;
9 use core::str::FromStr;
41 /// Adds the attribute to all items in the block.
42 macro_rules! cfg_block {
43 ($(#[$attr:meta]{$($it:item)*})*) => {$($(
49 /// Groups items that assume the pointer width is either 16/32/64, and has to be altered if
50 /// support for larger/smaller pointer widths are added in the future.
51 macro_rules! assume_usize_width {
52 {$($it:item)*} => {#[cfg(not(any(
53 target_pointer_width = "16", target_pointer_width = "32", target_pointer_width = "64")))]
54 compile_error!("The current tests of try_from on usize/isize assume that \
55 the pointer width is either 16, 32, or 64");
60 /// Helper function for testing numeric operations
61 pub fn test_num<T>(ten: T, two: T)
72 assert_eq!(ten.add(two), ten + two);
73 assert_eq!(ten.sub(two), ten - two);
74 assert_eq!(ten.mul(two), ten * two);
75 assert_eq!(ten.div(two), ten / two);
76 assert_eq!(ten.rem(two), ten % two);
79 /// Helper function for asserting number parsing returns a specific error
80 fn test_parse<T>(num_str: &str, expected: Result<T, IntErrorKind>)
82 T: FromStr<Err = ParseIntError>,
83 Result<T, IntErrorKind>: PartialEq + Debug,
85 assert_eq!(num_str.parse::<T>().map_err(|e| e.kind().clone()), expected)
89 fn from_str_issue7588() {
90 let u: Option<u8> = u8::from_str_radix("1000", 10).ok();
92 let s: Option<i16> = i16::from_str_radix("80000", 10).ok();
97 fn test_int_from_str_overflow() {
98 test_parse::<i8>("127", Ok(127));
99 test_parse::<i8>("128", Err(IntErrorKind::PosOverflow));
101 test_parse::<i8>("-128", Ok(-128));
102 test_parse::<i8>("-129", Err(IntErrorKind::NegOverflow));
104 test_parse::<i16>("32767", Ok(32_767));
105 test_parse::<i16>("32768", Err(IntErrorKind::PosOverflow));
107 test_parse::<i16>("-32768", Ok(-32_768));
108 test_parse::<i16>("-32769", Err(IntErrorKind::NegOverflow));
110 test_parse::<i32>("2147483647", Ok(2_147_483_647));
111 test_parse::<i32>("2147483648", Err(IntErrorKind::PosOverflow));
113 test_parse::<i32>("-2147483648", Ok(-2_147_483_648));
114 test_parse::<i32>("-2147483649", Err(IntErrorKind::NegOverflow));
116 test_parse::<i64>("9223372036854775807", Ok(9_223_372_036_854_775_807));
117 test_parse::<i64>("9223372036854775808", Err(IntErrorKind::PosOverflow));
119 test_parse::<i64>("-9223372036854775808", Ok(-9_223_372_036_854_775_808));
120 test_parse::<i64>("-9223372036854775809", Err(IntErrorKind::NegOverflow));
124 fn test_can_not_overflow() {
125 fn can_overflow<T>(radix: u32, input: &str) -> bool
127 T: std::convert::TryFrom<i8>,
129 !can_not_overflow::<T>(radix, T::try_from(-1_i8).is_ok(), input.as_bytes())
133 assert!(!can_overflow::<i8>(16, "F"));
134 assert!(!can_overflow::<u8>(16, "FF"));
136 assert!(!can_overflow::<i8>(10, "9"));
137 assert!(!can_overflow::<u8>(10, "99"));
141 // Not currently in std lib (issue: #27728)
142 fn format_radix<T>(mut x: T, radix: T) -> String
144 T: std::ops::Rem<Output = T>,
145 T: std::ops::Div<Output = T>,
146 T: std::cmp::PartialEq,
147 T: std::default::Default,
152 let mut result = vec![];
158 std::char::from_digit(m.try_into().ok().unwrap(), radix.try_into().ok().unwrap())
161 if x == T::default() {
165 result.into_iter().rev().collect()
171 let num = (<$t>::MAX as u128) + 1;
173 // Calcutate the string length for the smallest overflowing number:
174 let max_len_string = format_radix(num, base as u128);
175 // Ensure that string length is deemed to potentially overflow:
176 assert!(can_overflow::<$t>(base, &max_len_string));
181 check! { i8 i16 i32 i64 i128 isize usize u8 u16 u32 u64 }
183 // Check u128 separately:
185 let num = u128::MAX as u128;
186 let max_len_string = format_radix(num, base as u128);
187 // base 16 fits perfectly for u128 and won't overflow:
188 assert_eq!(can_overflow::<u128>(base, &max_len_string), base != 16);
193 fn test_leading_plus() {
194 test_parse::<u8>("+127", Ok(127));
195 test_parse::<i64>("+9223372036854775807", Ok(9223372036854775807));
200 test_parse::<i8>("--129", Err(IntErrorKind::InvalidDigit));
201 test_parse::<i8>("++129", Err(IntErrorKind::InvalidDigit));
202 test_parse::<u8>("Съешь", Err(IntErrorKind::InvalidDigit));
203 test_parse::<u8>("123Hello", Err(IntErrorKind::InvalidDigit));
204 test_parse::<i8>("--", Err(IntErrorKind::InvalidDigit));
205 test_parse::<i8>("-", Err(IntErrorKind::InvalidDigit));
206 test_parse::<i8>("+", Err(IntErrorKind::InvalidDigit));
207 test_parse::<u8>("-1", Err(IntErrorKind::InvalidDigit));
212 test_parse::<u8>("", Err(IntErrorKind::Empty));
216 fn test_infallible_try_from_int_error() {
217 let func = |x: i8| -> Result<i32, TryFromIntError> { Ok(x.try_into()?) };
219 assert!(func(0).is_ok());
222 macro_rules! test_impl_from {
223 ($fn_name:ident, bool, $target: ty) => {
226 let one: $target = 1;
227 let zero: $target = 0;
228 assert_eq!(one, <$target>::from(true));
229 assert_eq!(zero, <$target>::from(false));
232 ($fn_name: ident, $Small: ty, $Large: ty) => {
235 let small_max = <$Small>::MAX;
236 let small_min = <$Small>::MIN;
237 let large_max: $Large = small_max.into();
238 let large_min: $Large = small_min.into();
239 assert_eq!(large_max as $Small, small_max);
240 assert_eq!(large_min as $Small, small_min);
245 // Unsigned -> Unsigned
246 test_impl_from! { test_u8u16, u8, u16 }
247 test_impl_from! { test_u8u32, u8, u32 }
248 test_impl_from! { test_u8u64, u8, u64 }
249 test_impl_from! { test_u8usize, u8, usize }
250 test_impl_from! { test_u16u32, u16, u32 }
251 test_impl_from! { test_u16u64, u16, u64 }
252 test_impl_from! { test_u32u64, u32, u64 }
255 test_impl_from! { test_i8i16, i8, i16 }
256 test_impl_from! { test_i8i32, i8, i32 }
257 test_impl_from! { test_i8i64, i8, i64 }
258 test_impl_from! { test_i8isize, i8, isize }
259 test_impl_from! { test_i16i32, i16, i32 }
260 test_impl_from! { test_i16i64, i16, i64 }
261 test_impl_from! { test_i32i64, i32, i64 }
263 // Unsigned -> Signed
264 test_impl_from! { test_u8i16, u8, i16 }
265 test_impl_from! { test_u8i32, u8, i32 }
266 test_impl_from! { test_u8i64, u8, i64 }
267 test_impl_from! { test_u16i32, u16, i32 }
268 test_impl_from! { test_u16i64, u16, i64 }
269 test_impl_from! { test_u32i64, u32, i64 }
272 test_impl_from! { test_boolu8, bool, u8 }
273 test_impl_from! { test_boolu16, bool, u16 }
274 test_impl_from! { test_boolu32, bool, u32 }
275 test_impl_from! { test_boolu64, bool, u64 }
276 test_impl_from! { test_boolu128, bool, u128 }
277 test_impl_from! { test_booli8, bool, i8 }
278 test_impl_from! { test_booli16, bool, i16 }
279 test_impl_from! { test_booli32, bool, i32 }
280 test_impl_from! { test_booli64, bool, i64 }
281 test_impl_from! { test_booli128, bool, i128 }
284 test_impl_from! { test_i8f32, i8, f32 }
285 test_impl_from! { test_i8f64, i8, f64 }
286 test_impl_from! { test_i16f32, i16, f32 }
287 test_impl_from! { test_i16f64, i16, f64 }
288 test_impl_from! { test_i32f64, i32, f64 }
291 test_impl_from! { test_u8f32, u8, f32 }
292 test_impl_from! { test_u8f64, u8, f64 }
293 test_impl_from! { test_u16f32, u16, f32 }
294 test_impl_from! { test_u16f64, u16, f64 }
295 test_impl_from! { test_u32f64, u32, f64 }
300 let max: f64 = f32::MAX.into();
301 assert_eq!(max as f32, f32::MAX);
302 assert!(max.is_normal());
304 let min: f64 = f32::MIN.into();
305 assert_eq!(min as f32, f32::MIN);
306 assert!(min.is_normal());
308 let min_positive: f64 = f32::MIN_POSITIVE.into();
309 assert_eq!(min_positive as f32, f32::MIN_POSITIVE);
310 assert!(min_positive.is_normal());
312 let epsilon: f64 = f32::EPSILON.into();
313 assert_eq!(epsilon as f32, f32::EPSILON);
314 assert!(epsilon.is_normal());
316 let zero: f64 = (0.0f32).into();
317 assert_eq!(zero as f32, 0.0f32);
318 assert!(zero.is_sign_positive());
320 let neg_zero: f64 = (-0.0f32).into();
321 assert_eq!(neg_zero as f32, -0.0f32);
322 assert!(neg_zero.is_sign_negative());
324 let infinity: f64 = f32::INFINITY.into();
325 assert_eq!(infinity as f32, f32::INFINITY);
326 assert!(infinity.is_infinite());
327 assert!(infinity.is_sign_positive());
329 let neg_infinity: f64 = f32::NEG_INFINITY.into();
330 assert_eq!(neg_infinity as f32, f32::NEG_INFINITY);
331 assert!(neg_infinity.is_infinite());
332 assert!(neg_infinity.is_sign_negative());
334 let nan: f64 = f32::NAN.into();
335 assert!(nan.is_nan());
338 /// Conversions where the full width of $source can be represented as $target
339 macro_rules! test_impl_try_from_always_ok {
340 ($fn_name:ident, $source:ty, $target: ty) => {
343 let max = <$source>::MAX;
344 let min = <$source>::MIN;
345 let zero: $source = 0;
346 assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(), max as $target);
347 assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(), min as $target);
348 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target);
353 test_impl_try_from_always_ok! { test_try_u8u8, u8, u8 }
354 test_impl_try_from_always_ok! { test_try_u8u16, u8, u16 }
355 test_impl_try_from_always_ok! { test_try_u8u32, u8, u32 }
356 test_impl_try_from_always_ok! { test_try_u8u64, u8, u64 }
357 test_impl_try_from_always_ok! { test_try_u8u128, u8, u128 }
358 test_impl_try_from_always_ok! { test_try_u8i16, u8, i16 }
359 test_impl_try_from_always_ok! { test_try_u8i32, u8, i32 }
360 test_impl_try_from_always_ok! { test_try_u8i64, u8, i64 }
361 test_impl_try_from_always_ok! { test_try_u8i128, u8, i128 }
363 test_impl_try_from_always_ok! { test_try_u16u16, u16, u16 }
364 test_impl_try_from_always_ok! { test_try_u16u32, u16, u32 }
365 test_impl_try_from_always_ok! { test_try_u16u64, u16, u64 }
366 test_impl_try_from_always_ok! { test_try_u16u128, u16, u128 }
367 test_impl_try_from_always_ok! { test_try_u16i32, u16, i32 }
368 test_impl_try_from_always_ok! { test_try_u16i64, u16, i64 }
369 test_impl_try_from_always_ok! { test_try_u16i128, u16, i128 }
371 test_impl_try_from_always_ok! { test_try_u32u32, u32, u32 }
372 test_impl_try_from_always_ok! { test_try_u32u64, u32, u64 }
373 test_impl_try_from_always_ok! { test_try_u32u128, u32, u128 }
374 test_impl_try_from_always_ok! { test_try_u32i64, u32, i64 }
375 test_impl_try_from_always_ok! { test_try_u32i128, u32, i128 }
377 test_impl_try_from_always_ok! { test_try_u64u64, u64, u64 }
378 test_impl_try_from_always_ok! { test_try_u64u128, u64, u128 }
379 test_impl_try_from_always_ok! { test_try_u64i128, u64, i128 }
381 test_impl_try_from_always_ok! { test_try_u128u128, u128, u128 }
383 test_impl_try_from_always_ok! { test_try_i8i8, i8, i8 }
384 test_impl_try_from_always_ok! { test_try_i8i16, i8, i16 }
385 test_impl_try_from_always_ok! { test_try_i8i32, i8, i32 }
386 test_impl_try_from_always_ok! { test_try_i8i64, i8, i64 }
387 test_impl_try_from_always_ok! { test_try_i8i128, i8, i128 }
389 test_impl_try_from_always_ok! { test_try_i16i16, i16, i16 }
390 test_impl_try_from_always_ok! { test_try_i16i32, i16, i32 }
391 test_impl_try_from_always_ok! { test_try_i16i64, i16, i64 }
392 test_impl_try_from_always_ok! { test_try_i16i128, i16, i128 }
394 test_impl_try_from_always_ok! { test_try_i32i32, i32, i32 }
395 test_impl_try_from_always_ok! { test_try_i32i64, i32, i64 }
396 test_impl_try_from_always_ok! { test_try_i32i128, i32, i128 }
398 test_impl_try_from_always_ok! { test_try_i64i64, i64, i64 }
399 test_impl_try_from_always_ok! { test_try_i64i128, i64, i128 }
401 test_impl_try_from_always_ok! { test_try_i128i128, i128, i128 }
403 test_impl_try_from_always_ok! { test_try_usizeusize, usize, usize }
404 test_impl_try_from_always_ok! { test_try_isizeisize, isize, isize }
406 assume_usize_width! {
407 test_impl_try_from_always_ok! { test_try_u8usize, u8, usize }
408 test_impl_try_from_always_ok! { test_try_u8isize, u8, isize }
409 test_impl_try_from_always_ok! { test_try_i8isize, i8, isize }
411 test_impl_try_from_always_ok! { test_try_u16usize, u16, usize }
412 test_impl_try_from_always_ok! { test_try_i16isize, i16, isize }
414 test_impl_try_from_always_ok! { test_try_usizeu64, usize, u64 }
415 test_impl_try_from_always_ok! { test_try_usizeu128, usize, u128 }
416 test_impl_try_from_always_ok! { test_try_usizei128, usize, i128 }
418 test_impl_try_from_always_ok! { test_try_isizei64, isize, i64 }
419 test_impl_try_from_always_ok! { test_try_isizei128, isize, i128 }
422 #[cfg(target_pointer_width = "16")] {
423 test_impl_try_from_always_ok! { test_try_usizeu16, usize, u16 }
424 test_impl_try_from_always_ok! { test_try_isizei16, isize, i16 }
425 test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
426 test_impl_try_from_always_ok! { test_try_usizei32, usize, i32 }
427 test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
428 test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
431 #[cfg(target_pointer_width = "32")] {
432 test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
433 test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
434 test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
435 test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
436 test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
437 test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
440 #[cfg(target_pointer_width = "64")] {
441 test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
442 test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
443 test_impl_try_from_always_ok! { test_try_u32isize, u32, isize }
444 test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
445 test_impl_try_from_always_ok! { test_try_u64usize, u64, usize }
446 test_impl_try_from_always_ok! { test_try_i64isize, i64, isize }
451 /// Conversions where max of $source can be represented as $target,
452 macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok {
453 ($fn_name:ident, $source:ty, $target:ty) => {
456 let max = <$source>::MAX;
457 let min = <$source>::MIN;
458 let zero: $source = 0;
459 let neg_one: $source = -1;
460 assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(), max as $target);
461 assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
462 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target);
463 assert!(<$target as TryFrom<$source>>::try_from(neg_one).is_err());
468 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u8, i8, u8 }
469 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u16, i8, u16 }
470 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u32, i8, u32 }
471 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u64, i8, u64 }
472 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u128, i8, u128 }
474 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u16, i16, u16 }
475 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u32, i16, u32 }
476 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u64, i16, u64 }
477 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u128, i16, u128 }
479 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u32, i32, u32 }
480 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u64, i32, u64 }
481 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u128, i32, u128 }
483 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u64, i64, u64 }
484 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u128, i64, u128 }
486 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i128u128, i128, u128 }
488 assume_usize_width! {
489 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8usize, i8, usize }
490 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16usize, i16, usize }
492 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu64, isize, u64 }
493 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu128, isize, u128 }
494 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeusize, isize, usize }
497 #[cfg(target_pointer_width = "16")] {
498 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu16, isize, u16 }
499 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
502 #[cfg(target_pointer_width = "32")] {
503 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
505 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
508 #[cfg(target_pointer_width = "64")] {
509 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
510 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64usize, i64, usize }
515 /// Conversions where max of $source can not be represented as $target,
517 macro_rules! test_impl_try_from_unsigned_to_signed_upper_err {
518 ($fn_name:ident, $source:ty, $target:ty) => {
521 let max = <$source>::MAX;
522 let min = <$source>::MIN;
523 let zero: $source = 0;
524 assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
525 assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(), min as $target);
526 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target);
531 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u8i8, u8, i8 }
533 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i8, u16, i8 }
534 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i16, u16, i16 }
536 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i8, u32, i8 }
537 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i16, u32, i16 }
538 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i32, u32, i32 }
540 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i8, u64, i8 }
541 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i16, u64, i16 }
542 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i32, u64, i32 }
543 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i64, u64, i64 }
545 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i8, u128, i8 }
546 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i16, u128, i16 }
547 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i32, u128, i32 }
548 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i64, u128, i64 }
549 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i128, u128, i128 }
551 assume_usize_width! {
552 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64isize, u64, isize }
553 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128isize, u128, isize }
555 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei8, usize, i8 }
556 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei16, usize, i16 }
557 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizeisize, usize, isize }
560 #[cfg(target_pointer_width = "16")] {
561 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16isize, u16, isize }
562 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
565 #[cfg(target_pointer_width = "32")] {
566 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
567 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
570 #[cfg(target_pointer_width = "64")] {
571 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
572 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei64, usize, i64 }
577 /// Conversions where min/max of $source can not be represented as $target.
578 macro_rules! test_impl_try_from_same_sign_err {
579 ($fn_name:ident, $source:ty, $target:ty) => {
582 let max = <$source>::MAX;
583 let min = <$source>::MIN;
584 let zero: $source = 0;
585 let t_max = <$target>::MAX;
586 let t_min = <$target>::MIN;
587 assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
589 assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
591 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target);
593 <$target as TryFrom<$source>>::try_from(t_max as $source).unwrap(),
597 <$target as TryFrom<$source>>::try_from(t_min as $source).unwrap(),
604 test_impl_try_from_same_sign_err! { test_try_u16u8, u16, u8 }
606 test_impl_try_from_same_sign_err! { test_try_u32u8, u32, u8 }
607 test_impl_try_from_same_sign_err! { test_try_u32u16, u32, u16 }
609 test_impl_try_from_same_sign_err! { test_try_u64u8, u64, u8 }
610 test_impl_try_from_same_sign_err! { test_try_u64u16, u64, u16 }
611 test_impl_try_from_same_sign_err! { test_try_u64u32, u64, u32 }
613 test_impl_try_from_same_sign_err! { test_try_u128u8, u128, u8 }
614 test_impl_try_from_same_sign_err! { test_try_u128u16, u128, u16 }
615 test_impl_try_from_same_sign_err! { test_try_u128u32, u128, u32 }
616 test_impl_try_from_same_sign_err! { test_try_u128u64, u128, u64 }
618 test_impl_try_from_same_sign_err! { test_try_i16i8, i16, i8 }
619 test_impl_try_from_same_sign_err! { test_try_isizei8, isize, i8 }
621 test_impl_try_from_same_sign_err! { test_try_i32i8, i32, i8 }
622 test_impl_try_from_same_sign_err! { test_try_i32i16, i32, i16 }
624 test_impl_try_from_same_sign_err! { test_try_i64i8, i64, i8 }
625 test_impl_try_from_same_sign_err! { test_try_i64i16, i64, i16 }
626 test_impl_try_from_same_sign_err! { test_try_i64i32, i64, i32 }
628 test_impl_try_from_same_sign_err! { test_try_i128i8, i128, i8 }
629 test_impl_try_from_same_sign_err! { test_try_i128i16, i128, i16 }
630 test_impl_try_from_same_sign_err! { test_try_i128i32, i128, i32 }
631 test_impl_try_from_same_sign_err! { test_try_i128i64, i128, i64 }
633 assume_usize_width! {
634 test_impl_try_from_same_sign_err! { test_try_usizeu8, usize, u8 }
635 test_impl_try_from_same_sign_err! { test_try_u128usize, u128, usize }
636 test_impl_try_from_same_sign_err! { test_try_i128isize, i128, isize }
639 #[cfg(target_pointer_width = "16")] {
640 test_impl_try_from_same_sign_err! { test_try_u32usize, u32, usize }
641 test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
643 test_impl_try_from_same_sign_err! { test_try_i32isize, i32, isize }
644 test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
647 #[cfg(target_pointer_width = "32")] {
648 test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
649 test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
651 test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
652 test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
655 #[cfg(target_pointer_width = "64")] {
656 test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
657 test_impl_try_from_same_sign_err! { test_try_usizeu32, usize, u32 }
659 test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
660 test_impl_try_from_same_sign_err! { test_try_isizei32, isize, i32 }
665 /// Conversions where neither the min nor the max of $source can be represented by
666 /// $target, but max/min of the target can be represented by the source.
667 macro_rules! test_impl_try_from_signed_to_unsigned_err {
668 ($fn_name:ident, $source:ty, $target:ty) => {
671 let max = <$source>::MAX;
672 let min = <$source>::MIN;
673 let zero: $source = 0;
674 let t_max = <$target>::MAX;
675 let t_min = <$target>::MIN;
676 assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
677 assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
678 assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(), zero as $target);
680 <$target as TryFrom<$source>>::try_from(t_max as $source).unwrap(),
684 <$target as TryFrom<$source>>::try_from(t_min as $source).unwrap(),
691 test_impl_try_from_signed_to_unsigned_err! { test_try_i16u8, i16, u8 }
693 test_impl_try_from_signed_to_unsigned_err! { test_try_i32u8, i32, u8 }
694 test_impl_try_from_signed_to_unsigned_err! { test_try_i32u16, i32, u16 }
696 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u8, i64, u8 }
697 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u16, i64, u16 }
698 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }
700 test_impl_try_from_signed_to_unsigned_err! { test_try_i128u8, i128, u8 }
701 test_impl_try_from_signed_to_unsigned_err! { test_try_i128u16, i128, u16 }
702 test_impl_try_from_signed_to_unsigned_err! { test_try_i128u32, i128, u32 }
703 test_impl_try_from_signed_to_unsigned_err! { test_try_i128u64, i128, u64 }
705 assume_usize_width! {
706 test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu8, isize, u8 }
707 test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize }
710 #[cfg(target_pointer_width = "16")] {
711 test_impl_try_from_signed_to_unsigned_err! { test_try_i32usize, i32, usize }
712 test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
714 #[cfg(target_pointer_width = "32")] {
715 test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
717 test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
719 #[cfg(target_pointer_width = "64")] {
720 test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
721 test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu32, isize, u32 }
726 macro_rules! test_float {
727 ($modname: ident, $fty: ty, $inf: expr, $neginf: expr, $nan: expr) => {
731 assert_eq!((0.0 as $fty).min(0.0), 0.0);
732 assert!((0.0 as $fty).min(0.0).is_sign_positive());
733 assert_eq!((-0.0 as $fty).min(-0.0), -0.0);
734 assert!((-0.0 as $fty).min(-0.0).is_sign_negative());
735 assert_eq!((9.0 as $fty).min(9.0), 9.0);
736 assert_eq!((-9.0 as $fty).min(0.0), -9.0);
737 assert_eq!((0.0 as $fty).min(9.0), 0.0);
738 assert!((0.0 as $fty).min(9.0).is_sign_positive());
739 assert_eq!((-0.0 as $fty).min(9.0), -0.0);
740 assert!((-0.0 as $fty).min(9.0).is_sign_negative());
741 assert_eq!((-0.0 as $fty).min(-9.0), -9.0);
742 assert_eq!(($inf as $fty).min(9.0), 9.0);
743 assert_eq!((9.0 as $fty).min($inf), 9.0);
744 assert_eq!(($inf as $fty).min(-9.0), -9.0);
745 assert_eq!((-9.0 as $fty).min($inf), -9.0);
746 assert_eq!(($neginf as $fty).min(9.0), $neginf);
747 assert_eq!((9.0 as $fty).min($neginf), $neginf);
748 assert_eq!(($neginf as $fty).min(-9.0), $neginf);
749 assert_eq!((-9.0 as $fty).min($neginf), $neginf);
750 assert_eq!(($nan as $fty).min(9.0), 9.0);
751 assert_eq!(($nan as $fty).min(-9.0), -9.0);
752 assert_eq!((9.0 as $fty).min($nan), 9.0);
753 assert_eq!((-9.0 as $fty).min($nan), -9.0);
754 assert!(($nan as $fty).min($nan).is_nan());
758 assert_eq!((0.0 as $fty).max(0.0), 0.0);
759 assert!((0.0 as $fty).max(0.0).is_sign_positive());
760 assert_eq!((-0.0 as $fty).max(-0.0), -0.0);
761 assert!((-0.0 as $fty).max(-0.0).is_sign_negative());
762 assert_eq!((9.0 as $fty).max(9.0), 9.0);
763 assert_eq!((-9.0 as $fty).max(0.0), 0.0);
764 assert!((-9.0 as $fty).max(0.0).is_sign_positive());
765 assert_eq!((-9.0 as $fty).max(-0.0), -0.0);
766 assert!((-9.0 as $fty).max(-0.0).is_sign_negative());
767 assert_eq!((0.0 as $fty).max(9.0), 9.0);
768 assert_eq!((0.0 as $fty).max(-9.0), 0.0);
769 assert!((0.0 as $fty).max(-9.0).is_sign_positive());
770 assert_eq!((-0.0 as $fty).max(-9.0), -0.0);
771 assert!((-0.0 as $fty).max(-9.0).is_sign_negative());
772 assert_eq!(($inf as $fty).max(9.0), $inf);
773 assert_eq!((9.0 as $fty).max($inf), $inf);
774 assert_eq!(($inf as $fty).max(-9.0), $inf);
775 assert_eq!((-9.0 as $fty).max($inf), $inf);
776 assert_eq!(($neginf as $fty).max(9.0), 9.0);
777 assert_eq!((9.0 as $fty).max($neginf), 9.0);
778 assert_eq!(($neginf as $fty).max(-9.0), -9.0);
779 assert_eq!((-9.0 as $fty).max($neginf), -9.0);
780 assert_eq!(($nan as $fty).max(9.0), 9.0);
781 assert_eq!(($nan as $fty).max(-9.0), -9.0);
782 assert_eq!((9.0 as $fty).max($nan), 9.0);
783 assert_eq!((-9.0 as $fty).max($nan), -9.0);
784 assert!(($nan as $fty).max($nan).is_nan());
788 assert_eq!((0.0 as $fty).minimum(0.0), 0.0);
789 assert!((0.0 as $fty).minimum(0.0).is_sign_positive());
790 assert_eq!((-0.0 as $fty).minimum(0.0), -0.0);
791 assert!((-0.0 as $fty).minimum(0.0).is_sign_negative());
792 assert_eq!((-0.0 as $fty).minimum(-0.0), -0.0);
793 assert!((-0.0 as $fty).minimum(-0.0).is_sign_negative());
794 assert_eq!((9.0 as $fty).minimum(9.0), 9.0);
795 assert_eq!((-9.0 as $fty).minimum(0.0), -9.0);
796 assert_eq!((0.0 as $fty).minimum(9.0), 0.0);
797 assert!((0.0 as $fty).minimum(9.0).is_sign_positive());
798 assert_eq!((-0.0 as $fty).minimum(9.0), -0.0);
799 assert!((-0.0 as $fty).minimum(9.0).is_sign_negative());
800 assert_eq!((-0.0 as $fty).minimum(-9.0), -9.0);
801 assert_eq!(($inf as $fty).minimum(9.0), 9.0);
802 assert_eq!((9.0 as $fty).minimum($inf), 9.0);
803 assert_eq!(($inf as $fty).minimum(-9.0), -9.0);
804 assert_eq!((-9.0 as $fty).minimum($inf), -9.0);
805 assert_eq!(($neginf as $fty).minimum(9.0), $neginf);
806 assert_eq!((9.0 as $fty).minimum($neginf), $neginf);
807 assert_eq!(($neginf as $fty).minimum(-9.0), $neginf);
808 assert_eq!((-9.0 as $fty).minimum($neginf), $neginf);
809 assert!(($nan as $fty).minimum(9.0).is_nan());
810 assert!(($nan as $fty).minimum(-9.0).is_nan());
811 assert!((9.0 as $fty).minimum($nan).is_nan());
812 assert!((-9.0 as $fty).minimum($nan).is_nan());
813 assert!(($nan as $fty).minimum($nan).is_nan());
817 assert_eq!((0.0 as $fty).maximum(0.0), 0.0);
818 assert!((0.0 as $fty).maximum(0.0).is_sign_positive());
819 assert_eq!((-0.0 as $fty).maximum(0.0), 0.0);
820 assert!((-0.0 as $fty).maximum(0.0).is_sign_positive());
821 assert_eq!((-0.0 as $fty).maximum(-0.0), -0.0);
822 assert!((-0.0 as $fty).maximum(-0.0).is_sign_negative());
823 assert_eq!((9.0 as $fty).maximum(9.0), 9.0);
824 assert_eq!((-9.0 as $fty).maximum(0.0), 0.0);
825 assert!((-9.0 as $fty).maximum(0.0).is_sign_positive());
826 assert_eq!((-9.0 as $fty).maximum(-0.0), -0.0);
827 assert!((-9.0 as $fty).maximum(-0.0).is_sign_negative());
828 assert_eq!((0.0 as $fty).maximum(9.0), 9.0);
829 assert_eq!((0.0 as $fty).maximum(-9.0), 0.0);
830 assert!((0.0 as $fty).maximum(-9.0).is_sign_positive());
831 assert_eq!((-0.0 as $fty).maximum(-9.0), -0.0);
832 assert!((-0.0 as $fty).maximum(-9.0).is_sign_negative());
833 assert_eq!(($inf as $fty).maximum(9.0), $inf);
834 assert_eq!((9.0 as $fty).maximum($inf), $inf);
835 assert_eq!(($inf as $fty).maximum(-9.0), $inf);
836 assert_eq!((-9.0 as $fty).maximum($inf), $inf);
837 assert_eq!(($neginf as $fty).maximum(9.0), 9.0);
838 assert_eq!((9.0 as $fty).maximum($neginf), 9.0);
839 assert_eq!(($neginf as $fty).maximum(-9.0), -9.0);
840 assert_eq!((-9.0 as $fty).maximum($neginf), -9.0);
841 assert!(($nan as $fty).maximum(9.0).is_nan());
842 assert!(($nan as $fty).maximum(-9.0).is_nan());
843 assert!((9.0 as $fty).maximum($nan).is_nan());
844 assert!((-9.0 as $fty).maximum($nan).is_nan());
845 assert!(($nan as $fty).maximum($nan).is_nan());
850 assert!($inf.rem_euclid(a).is_nan());
851 assert_eq!(a.rem_euclid($inf), a);
852 assert!(a.rem_euclid($nan).is_nan());
853 assert!($inf.rem_euclid($inf).is_nan());
854 assert!($inf.rem_euclid($nan).is_nan());
855 assert!($nan.rem_euclid($inf).is_nan());
860 assert_eq!(a.div_euclid($inf), 0.0);
861 assert!(a.div_euclid($nan).is_nan());
862 assert!($inf.div_euclid($inf).is_nan());
863 assert!($inf.div_euclid($nan).is_nan());
864 assert!($nan.div_euclid($inf).is_nan());
870 test_float!(f32, f32, f32::INFINITY, f32::NEG_INFINITY, f32::NAN);
871 test_float!(f64, f64, f64::INFINITY, f64::NEG_INFINITY, f64::NAN);