1use crate::num::{IntErrorKind, TryFromIntError};
2
3#[unstable(feature = "convert_float_to_int", issue = "67057")]
6pub impl(self) trait FloatToInt<Int>: Sized {
7 #[unstable(feature = "convert_float_to_int", issue = "67057")]
8 #[doc(hidden)]
9 unsafe fn to_int_unchecked(self) -> Int;
10
11 #[unstable(feature = "float_conversions", issue = "159913")]
12 #[doc(hidden)]
13 fn to_int_saturating(self) -> Int;
14
15 #[unstable(feature = "float_conversions", issue = "159913")]
16 #[doc(hidden)]
17 fn to_int_checked(self) -> Option<Int>;
18}
19
20macro_rules! impl_float_to_int {
21 ($Float:ty => $($Int:ty),+) => {
22 $(
23 #[unstable(feature = "convert_float_to_int", issue = "67057")]
24 impl FloatToInt<$Int> for $Float {
25 #[inline]
26 unsafe fn to_int_unchecked(self) -> $Int {
27 unsafe { crate::intrinsics::float_to_int_unchecked(self) }
29 }
30 #[inline]
31 fn to_int_saturating(self) -> $Int {
32 self as $Int
34 }
35 #[inline]
36 fn to_int_checked(self) -> Option<$Int> {
37 if self - (<$Int>::MIN as $Float) > -1.0 && self < <$Int>::MAX as $Float + 1.0 {
43 Some(self as $Int)
44 } else {
45 None
46 }
47 }
48 }
49 )+
50 }
51}
52
53impl_float_to_int!(f16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
54impl_float_to_int!(f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
55impl_float_to_int!(f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
56impl_float_to_int!(f128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
57
58#[unstable(feature = "float_conversions", issue = "159913")]
61pub impl(self) trait FloatToFloat<Flt>: Sized {
62 #[unstable(feature = "float_conversions", issue = "159913")]
63 #[doc(hidden)]
64 fn cast(self) -> Flt;
65}
66
67macro_rules! impl_float_to_float {
68 ($Float:ty => $($Flt:ty),+) => {
69 $(
70 #[unstable(feature = "float_conversions", issue = "159913")]
71 impl FloatToFloat<$Flt> for $Float {
72 #[inline]
73 fn cast(self) -> $Flt {
74 self as $Flt
75 }
76 }
77 )+
78 }
79}
80
81impl_float_to_float!(f16 => f16, f32, f64, f128);
82impl_float_to_float!(f32 => f16, f32, f64, f128);
83impl_float_to_float!(f64 => f16, f32, f64, f128);
84impl_float_to_float!(f128 => f16, f32, f64, f128);
85
86macro_rules! impl_from_bool {
88 ($($int:ty)*) => {$(
89 #[stable(feature = "from_bool", since = "1.28.0")]
90 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
91 const impl From<bool> for $int {
92 #[doc = concat!("[`", stringify!($int), "`]")]
94 #[doc = concat!("assert_eq!(", stringify!($int), "::from(false), 0);")]
100 #[doc = concat!("assert_eq!(", stringify!($int), "::from(true), 1);")]
102 #[inline(always)]
104 fn from(b: bool) -> Self {
105 b as Self
106 }
107 }
108 )*}
109}
110
111impl_from_bool!(u8 u16 u32 u64 u128 usize);
113impl_from_bool!(i8 i16 i32 i64 i128 isize);
114
115macro_rules! impl_from {
117 ($small:ty => $large:ty, $(#[$attrs:meta]),+) => {
118 $(#[$attrs])+
119 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
120 const impl From<$small> for $large {
121 #[doc = concat!("Converts from [`", stringify!($small), "`] to [`", stringify!($large), "`] losslessly.")]
122 #[inline(always)]
123 fn from(small: $small) -> Self {
124 debug_assert!(<$large>::MIN as i128 <= <$small>::MIN as i128);
125 debug_assert!(<$small>::MAX as u128 <= <$large>::MAX as u128);
126 small as Self
127 }
128 }
129 }
130}
131
132impl_from!(u8 => u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
134impl_from!(u8 => u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
135impl_from!(u8 => u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
136impl_from!(u8 => u128, #[stable(feature = "i128", since = "1.26.0")]);
137impl_from!(u8 => usize, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
138impl_from!(u16 => u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
139impl_from!(u16 => u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
140impl_from!(u16 => u128, #[stable(feature = "i128", since = "1.26.0")]);
141impl_from!(u32 => u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
142impl_from!(u32 => u128, #[stable(feature = "i128", since = "1.26.0")]);
143impl_from!(u64 => u128, #[stable(feature = "i128", since = "1.26.0")]);
144
145impl_from!(i8 => i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
147impl_from!(i8 => i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
148impl_from!(i8 => i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
149impl_from!(i8 => i128, #[stable(feature = "i128", since = "1.26.0")]);
150impl_from!(i8 => isize, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
151impl_from!(i16 => i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
152impl_from!(i16 => i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
153impl_from!(i16 => i128, #[stable(feature = "i128", since = "1.26.0")]);
154impl_from!(i32 => i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
155impl_from!(i32 => i128, #[stable(feature = "i128", since = "1.26.0")]);
156impl_from!(i64 => i128, #[stable(feature = "i128", since = "1.26.0")]);
157
158impl_from!(u8 => i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
160impl_from!(u8 => i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
161impl_from!(u8 => i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
162impl_from!(u8 => i128, #[stable(feature = "i128", since = "1.26.0")]);
163impl_from!(u16 => i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
164impl_from!(u16 => i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
165impl_from!(u16 => i128, #[stable(feature = "i128", since = "1.26.0")]);
166impl_from!(u32 => i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
167impl_from!(u32 => i128, #[stable(feature = "i128", since = "1.26.0")]);
168impl_from!(u64 => i128, #[stable(feature = "i128", since = "1.26.0")]);
169
170impl_from!(u16 => usize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")]);
174impl_from!(u8 => isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")]);
175impl_from!(i16 => isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")]);
176
177impl_from!(i8 => f16, #[unstable(feature = "f16", issue = "116909")], #[unstable_feature_bound(f16)]);
196impl_from!(i8 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
197impl_from!(i8 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
198impl_from!(i8 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
199impl_from!(i16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
200impl_from!(i16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
201impl_from!(i16 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
202impl_from!(i32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
203impl_from!(i32 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
204impl_from!(i64 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
205
206impl_from!(u8 => f16, #[unstable(feature = "f16", issue = "116909")], #[unstable_feature_bound(f16)]);
208impl_from!(u8 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
209impl_from!(u8 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
210impl_from!(u8 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
211impl_from!(u16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
212impl_from!(u16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
213impl_from!(u16 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
214impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
215impl_from!(u32 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
216impl_from!(u64 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
217
218impl_from!(f16 => f32, #[unstable(feature = "f32_from_f16", issue = "154005")], #[unstable_feature_bound(f32_from_f16)]);
227impl_from!(f16 => f64, #[unstable(feature = "f16", issue = "116909")], #[unstable_feature_bound(f16)]);
228impl_from!(f16 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f16, f128)]);
230impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
231impl_from!(f32 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
232impl_from!(f64 => f128, #[unstable(feature = "f128", issue = "116909")], #[unstable_feature_bound(f128)]);
233
234macro_rules! impl_float_from_bool {
235 (
236 $(#[$attr:meta])*
237 $float:ty $(;
238 doctest_prefix: $(#[doc = $doctest_prefix:literal])*
239 doctest_suffix: $(#[doc = $doctest_suffix:literal])*
240 )?
241 ) => {
242 $(#[$attr])*
243 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
244 const impl From<bool> for $float {
245 #[doc = concat!("Converts a [`bool`] to [`", stringify!($float),"`] losslessly.")]
246 $($(#[doc = $doctest_prefix])*)?
251 #[doc = concat!("let x = ", stringify!($float), "::from(false);")]
252 #[doc = concat!("let y = ", stringify!($float), "::from(true);")]
256 $($(#[doc = $doctest_suffix])*)?
258 #[inline]
260 fn from(small: bool) -> Self {
261 small as u8 as Self
262 }
263 }
264 };
265}
266
267impl_float_from_bool!(
269 #[unstable(feature = "f16", issue = "116909")]
270 #[unstable_feature_bound(f16)]
271 f16;
272 doctest_prefix:
273 doctest_suffix:
279 );
281impl_float_from_bool!(
282 #[stable(feature = "float_from_bool", since = "1.68.0")]
283 f32
284);
285impl_float_from_bool!(
286 #[stable(feature = "float_from_bool", since = "1.68.0")]
287 f64
288);
289impl_float_from_bool!(
290 #[unstable(feature = "f128", issue = "116909")]
291 #[unstable_feature_bound(f128)]
292 f128;
293 doctest_prefix:
294 doctest_suffix:
299 );
301
302macro_rules! impl_try_from_unbounded {
304 ($source:ty => $($target:ty),+) => {$(
305 #[stable(feature = "try_from", since = "1.34.0")]
306 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
307 const impl TryFrom<$source> for $target {
308 type Error = TryFromIntError;
309
310 #[inline]
314 fn try_from(value: $source) -> Result<Self, Self::Error> {
315 Ok(value as Self)
316 }
317 }
318 )*}
319}
320
321macro_rules! impl_try_from_lower_bounded {
323 ($source:ty => $($target:ty),+) => {$(
324 #[stable(feature = "try_from", since = "1.34.0")]
325 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
326 const impl TryFrom<$source> for $target {
327 type Error = TryFromIntError;
328
329 #[inline]
333 fn try_from(u: $source) -> Result<Self, Self::Error> {
334 if u >= 0 {
335 Ok(u as Self)
336 } else {
337 Err(TryFromIntError(IntErrorKind::NegOverflow))
338 }
339 }
340 }
341 )*}
342}
343
344macro_rules! impl_try_from_upper_bounded {
346 ($source:ty => $($target:ty),+) => {$(
347 #[stable(feature = "try_from", since = "1.34.0")]
348 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
349 const impl TryFrom<$source> for $target {
350 type Error = TryFromIntError;
351
352 #[inline]
356 fn try_from(u: $source) -> Result<Self, Self::Error> {
357 if u > (Self::MAX as $source) {
358 Err(TryFromIntError(IntErrorKind::PosOverflow))
359 } else {
360 Ok(u as Self)
361 }
362 }
363 }
364 )*}
365}
366
367macro_rules! impl_try_from_both_bounded {
369 ($source:ty => $($target:ty),+) => {$(
370 #[stable(feature = "try_from", since = "1.34.0")]
371 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
372 const impl TryFrom<$source> for $target {
373 type Error = TryFromIntError;
374
375 #[inline]
379 fn try_from(u: $source) -> Result<Self, Self::Error> {
380 let min = Self::MIN as $source;
381 let max = Self::MAX as $source;
382 if u < min {
383 Err(TryFromIntError(IntErrorKind::NegOverflow))
384 } else if u > max {
385 Err(TryFromIntError(IntErrorKind::PosOverflow))
386 } else {
387 Ok(u as Self)
388 }
389 }
390 }
391 )*}
392}
393
394macro_rules! impl_try_from_integer_for_bool {
396 ($signedness:ident $($int:ty)+) => {$(
397 #[stable(feature = "bool_try_from_int", since = "1.95.0")]
398 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
399 const impl TryFrom<$int> for bool {
400 type Error = TryFromIntError;
401
402 #[doc = concat!("assert_eq!(bool::try_from(0_", stringify!($int), "), Ok(false));")]
409 #[doc = concat!("assert_eq!(bool::try_from(1_", stringify!($int), "), Ok(true));")]
411 #[doc = concat!("assert!(bool::try_from(2_", stringify!($int), ").is_err());")]
413 #[inline]
415 fn try_from(i: $int) -> Result<Self, Self::Error> {
416 sign_dependent_expr!{
417 $signedness ?
418 if signed {
419 match i {
420 0 => Ok(false),
421 1 => Ok(true),
422 ..0 => Err(TryFromIntError(IntErrorKind::NegOverflow)),
423 2.. => Err(TryFromIntError(IntErrorKind::PosOverflow)),
424 }
425 }
426 if unsigned {
427 match i {
428 0 => Ok(false),
429 1 => Ok(true),
430 2.. => Err(TryFromIntError(IntErrorKind::PosOverflow)),
431 }
432 }
433 }
434 }
435 }
436 )*}
437}
438
439macro_rules! rev {
440 ($mac:ident, $source:ty => $($target:ty),+) => {$(
441 $mac!($target => $source);
442 )*}
443}
444
445impl_try_from_integer_for_bool!(unsigned u128 u64 u32 u16 u8);
447impl_try_from_integer_for_bool!(signed i128 i64 i32 i16 i8);
448
449impl_try_from_upper_bounded!(u16 => u8);
451impl_try_from_upper_bounded!(u32 => u8, u16);
452impl_try_from_upper_bounded!(u64 => u8, u16, u32);
453impl_try_from_upper_bounded!(u128 => u8, u16, u32, u64);
454
455impl_try_from_both_bounded!(i16 => i8);
457impl_try_from_both_bounded!(i32 => i8, i16);
458impl_try_from_both_bounded!(i64 => i8, i16, i32);
459impl_try_from_both_bounded!(i128 => i8, i16, i32, i64);
460
461impl_try_from_upper_bounded!(u8 => i8);
463impl_try_from_upper_bounded!(u16 => i8, i16);
464impl_try_from_upper_bounded!(u32 => i8, i16, i32);
465impl_try_from_upper_bounded!(u64 => i8, i16, i32, i64);
466impl_try_from_upper_bounded!(u128 => i8, i16, i32, i64, i128);
467
468impl_try_from_lower_bounded!(i8 => u8, u16, u32, u64, u128);
470impl_try_from_both_bounded!(i16 => u8);
471impl_try_from_lower_bounded!(i16 => u16, u32, u64, u128);
472impl_try_from_both_bounded!(i32 => u8, u16);
473impl_try_from_lower_bounded!(i32 => u32, u64, u128);
474impl_try_from_both_bounded!(i64 => u8, u16, u32);
475impl_try_from_lower_bounded!(i64 => u64, u128);
476impl_try_from_both_bounded!(i128 => u8, u16, u32, u64);
477impl_try_from_lower_bounded!(i128 => u128);
478
479impl_try_from_upper_bounded!(usize => isize);
481impl_try_from_lower_bounded!(isize => usize);
482
483#[cfg(target_pointer_width = "16")]
484mod ptr_try_from_impls {
485 use super::{IntErrorKind, TryFromIntError};
486
487 impl_try_from_upper_bounded!(usize => u8);
488 impl_try_from_unbounded!(usize => u16, u32, u64, u128);
489 impl_try_from_upper_bounded!(usize => i8, i16);
490 impl_try_from_unbounded!(usize => i32, i64, i128);
491
492 impl_try_from_both_bounded!(isize => u8);
493 impl_try_from_lower_bounded!(isize => u16, u32, u64, u128);
494 impl_try_from_both_bounded!(isize => i8);
495 impl_try_from_unbounded!(isize => i16, i32, i64, i128);
496
497 rev!(impl_try_from_upper_bounded, usize => u32, u64, u128);
498 rev!(impl_try_from_lower_bounded, usize => i8, i16);
499 rev!(impl_try_from_both_bounded, usize => i32, i64, i128);
500
501 rev!(impl_try_from_upper_bounded, isize => u16, u32, u64, u128);
502 rev!(impl_try_from_both_bounded, isize => i32, i64, i128);
503}
504
505#[cfg(target_pointer_width = "32")]
506mod ptr_try_from_impls {
507 use super::{IntErrorKind, TryFromIntError};
508
509 impl_try_from_upper_bounded!(usize => u8, u16);
510 impl_try_from_unbounded!(usize => u32, u64, u128);
511 impl_try_from_upper_bounded!(usize => i8, i16, i32);
512 impl_try_from_unbounded!(usize => i64, i128);
513
514 impl_try_from_both_bounded!(isize => u8, u16);
515 impl_try_from_lower_bounded!(isize => u32, u64, u128);
516 impl_try_from_both_bounded!(isize => i8, i16);
517 impl_try_from_unbounded!(isize => i32, i64, i128);
518
519 rev!(impl_try_from_unbounded, usize => u32);
520 rev!(impl_try_from_upper_bounded, usize => u64, u128);
521 rev!(impl_try_from_lower_bounded, usize => i8, i16, i32);
522 rev!(impl_try_from_both_bounded, usize => i64, i128);
523
524 rev!(impl_try_from_unbounded, isize => u16);
525 rev!(impl_try_from_upper_bounded, isize => u32, u64, u128);
526 rev!(impl_try_from_unbounded, isize => i32);
527 rev!(impl_try_from_both_bounded, isize => i64, i128);
528}
529
530#[cfg(target_pointer_width = "64")]
531mod ptr_try_from_impls {
532 use super::{IntErrorKind, TryFromIntError};
533
534 impl_try_from_upper_bounded!(usize => u8, u16, u32);
535 impl_try_from_unbounded!(usize => u64, u128);
536 impl_try_from_upper_bounded!(usize => i8, i16, i32, i64);
537 impl_try_from_unbounded!(usize => i128);
538
539 impl_try_from_both_bounded!(isize => u8, u16, u32);
540 impl_try_from_lower_bounded!(isize => u64, u128);
541 impl_try_from_both_bounded!(isize => i8, i16, i32);
542 impl_try_from_unbounded!(isize => i64, i128);
543
544 rev!(impl_try_from_unbounded, usize => u32, u64);
545 rev!(impl_try_from_upper_bounded, usize => u128);
546 rev!(impl_try_from_lower_bounded, usize => i8, i16, i32, i64);
547 rev!(impl_try_from_both_bounded, usize => i128);
548
549 rev!(impl_try_from_unbounded, isize => u16, u32);
550 rev!(impl_try_from_upper_bounded, isize => u64, u128);
551 rev!(impl_try_from_unbounded, isize => i32, i64);
552 rev!(impl_try_from_both_bounded, isize => i128);
553}
554
555use crate::num::NonZero;
557
558macro_rules! impl_nonzero_int_from_nonzero_int {
559 ($Small:ty => $Large:ty) => {
560 #[stable(feature = "nz_int_conv", since = "1.41.0")]
561 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
562 const impl From<NonZero<$Small>> for NonZero<$Large> {
563 #[doc = concat!("Converts <code>[NonZero]\\<[", stringify!($Small), "]></code> ")]
566 #[doc = concat!("to <code>[NonZero]\\<[", stringify!($Large), "]></code> losslessly.")]
567 #[inline]
568 fn from(small: NonZero<$Small>) -> Self {
569 unsafe { Self::new_unchecked(From::from(small.get())) }
571 }
572 }
573 };
574}
575
576impl_nonzero_int_from_nonzero_int!(u8 => u16);
578impl_nonzero_int_from_nonzero_int!(u8 => u32);
579impl_nonzero_int_from_nonzero_int!(u8 => u64);
580impl_nonzero_int_from_nonzero_int!(u8 => u128);
581impl_nonzero_int_from_nonzero_int!(u8 => usize);
582impl_nonzero_int_from_nonzero_int!(u16 => u32);
583impl_nonzero_int_from_nonzero_int!(u16 => u64);
584impl_nonzero_int_from_nonzero_int!(u16 => u128);
585impl_nonzero_int_from_nonzero_int!(u16 => usize);
586impl_nonzero_int_from_nonzero_int!(u32 => u64);
587impl_nonzero_int_from_nonzero_int!(u32 => u128);
588impl_nonzero_int_from_nonzero_int!(u64 => u128);
589
590impl_nonzero_int_from_nonzero_int!(i8 => i16);
592impl_nonzero_int_from_nonzero_int!(i8 => i32);
593impl_nonzero_int_from_nonzero_int!(i8 => i64);
594impl_nonzero_int_from_nonzero_int!(i8 => i128);
595impl_nonzero_int_from_nonzero_int!(i8 => isize);
596impl_nonzero_int_from_nonzero_int!(i16 => i32);
597impl_nonzero_int_from_nonzero_int!(i16 => i64);
598impl_nonzero_int_from_nonzero_int!(i16 => i128);
599impl_nonzero_int_from_nonzero_int!(i16 => isize);
600impl_nonzero_int_from_nonzero_int!(i32 => i64);
601impl_nonzero_int_from_nonzero_int!(i32 => i128);
602impl_nonzero_int_from_nonzero_int!(i64 => i128);
603
604impl_nonzero_int_from_nonzero_int!(u8 => i16);
606impl_nonzero_int_from_nonzero_int!(u8 => i32);
607impl_nonzero_int_from_nonzero_int!(u8 => i64);
608impl_nonzero_int_from_nonzero_int!(u8 => i128);
609impl_nonzero_int_from_nonzero_int!(u8 => isize);
610impl_nonzero_int_from_nonzero_int!(u16 => i32);
611impl_nonzero_int_from_nonzero_int!(u16 => i64);
612impl_nonzero_int_from_nonzero_int!(u16 => i128);
613impl_nonzero_int_from_nonzero_int!(u32 => i64);
614impl_nonzero_int_from_nonzero_int!(u32 => i128);
615impl_nonzero_int_from_nonzero_int!(u64 => i128);
616
617macro_rules! impl_nonzero_int_try_from_int {
618 ($Int:ty) => {
619 #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")]
620 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
621 const impl TryFrom<$Int> for NonZero<$Int> {
622 type Error = TryFromIntError;
623
624 #[doc = concat!("Attempts to convert [`", stringify!($Int), "`] ")]
627 #[doc = concat!("to <code>[NonZero]\\<[", stringify!($Int), "]></code>.")]
628 #[inline]
629 fn try_from(value: $Int) -> Result<Self, Self::Error> {
630 Self::new(value).ok_or(TryFromIntError(IntErrorKind::Zero))
631 }
632 }
633 };
634}
635
636impl_nonzero_int_try_from_int!(u8);
638impl_nonzero_int_try_from_int!(u16);
639impl_nonzero_int_try_from_int!(u32);
640impl_nonzero_int_try_from_int!(u64);
641impl_nonzero_int_try_from_int!(u128);
642impl_nonzero_int_try_from_int!(usize);
643impl_nonzero_int_try_from_int!(i8);
644impl_nonzero_int_try_from_int!(i16);
645impl_nonzero_int_try_from_int!(i32);
646impl_nonzero_int_try_from_int!(i64);
647impl_nonzero_int_try_from_int!(i128);
648impl_nonzero_int_try_from_int!(isize);
649
650macro_rules! impl_nonzero_int_try_from_nonzero_int {
651 ($source:ty => $($target:ty),+) => {$(
652 #[stable(feature = "nzint_try_from_nzint_conv", since = "1.49.0")]
653 #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
654 const impl TryFrom<NonZero<$source>> for NonZero<$target> {
655 type Error = TryFromIntError;
656
657 #[doc = concat!("Attempts to convert <code>[NonZero]\\<[", stringify!($source), "]></code> ")]
660 #[doc = concat!("to <code>[NonZero]\\<[", stringify!($target), "]></code>.")]
661 #[inline]
662 fn try_from(value: NonZero<$source>) -> Result<Self, Self::Error> {
663 Ok(unsafe { Self::new_unchecked(<$target>::try_from(value.get())?) })
665 }
666 }
667 )*};
668}
669
670impl_nonzero_int_try_from_nonzero_int!(u16 => u8);
672impl_nonzero_int_try_from_nonzero_int!(u32 => u8, u16, usize);
673impl_nonzero_int_try_from_nonzero_int!(u64 => u8, u16, u32, usize);
674impl_nonzero_int_try_from_nonzero_int!(u128 => u8, u16, u32, u64, usize);
675impl_nonzero_int_try_from_nonzero_int!(usize => u8, u16, u32, u64, u128);
676
677impl_nonzero_int_try_from_nonzero_int!(i16 => i8);
679impl_nonzero_int_try_from_nonzero_int!(i32 => i8, i16, isize);
680impl_nonzero_int_try_from_nonzero_int!(i64 => i8, i16, i32, isize);
681impl_nonzero_int_try_from_nonzero_int!(i128 => i8, i16, i32, i64, isize);
682impl_nonzero_int_try_from_nonzero_int!(isize => i8, i16, i32, i64, i128);
683
684impl_nonzero_int_try_from_nonzero_int!(u8 => i8);
686impl_nonzero_int_try_from_nonzero_int!(u16 => i8, i16, isize);
687impl_nonzero_int_try_from_nonzero_int!(u32 => i8, i16, i32, isize);
688impl_nonzero_int_try_from_nonzero_int!(u64 => i8, i16, i32, i64, isize);
689impl_nonzero_int_try_from_nonzero_int!(u128 => i8, i16, i32, i64, i128, isize);
690impl_nonzero_int_try_from_nonzero_int!(usize => i8, i16, i32, i64, i128, isize);
691
692impl_nonzero_int_try_from_nonzero_int!(i8 => u8, u16, u32, u64, u128, usize);
694impl_nonzero_int_try_from_nonzero_int!(i16 => u8, u16, u32, u64, u128, usize);
695impl_nonzero_int_try_from_nonzero_int!(i32 => u8, u16, u32, u64, u128, usize);
696impl_nonzero_int_try_from_nonzero_int!(i64 => u8, u16, u32, u64, u128, usize);
697impl_nonzero_int_try_from_nonzero_int!(i128 => u8, u16, u32, u64, u128, usize);
698impl_nonzero_int_try_from_nonzero_int!(isize => u8, u16, u32, u64, u128, usize);
699
700#[unstable(feature = "integer_casts", issue = "157388")]
702#[rustc_const_unstable(feature = "integer_casts", issue = "157388")]
703pub impl(self) const trait BoundedCastFromInt<T>: Sized {
704 #[unstable(feature = "integer_casts", issue = "157388")]
706 fn wrapping_cast_from(value: T) -> Self;
707
708 #[unstable(feature = "integer_casts", issue = "157388")]
710 fn saturating_cast_from(value: T) -> Self;
711}
712
713#[unstable(feature = "integer_casts", issue = "157388")]
715#[rustc_const_unstable(feature = "integer_casts", issue = "157388")]
716pub impl(self) const trait CheckedCastFromInt<T>: Sized {
717 #[unstable(feature = "integer_casts", issue = "157388")]
719 fn checked_cast_from(value: T) -> Option<Self>;
720
721 #[unstable(feature = "integer_casts", issue = "157388")]
728 unsafe fn unchecked_cast_from(value: T) -> Self;
729
730 #[unstable(feature = "integer_casts", issue = "157388")]
736 fn strict_cast_from(value: T) -> Self;
737}
738
739macro_rules! impl_int_cast {
740 ($Src:ty as [$($Dst:ty),*]) => {$(
741 #[unstable(feature = "integer_casts", issue = "157388")]
742 #[rustc_const_unstable(feature = "integer_casts", issue = "157388")]
743 const impl CheckedCastFromInt<$Src> for $Dst {
744 #[inline]
745 fn checked_cast_from(value: $Src) -> Option<Self> {
746 value.try_into().ok()
747 }
748
749 #[inline(always)]
750 unsafe fn unchecked_cast_from(value: $Src) -> Self {
751 unsafe { value.try_into().unwrap_unchecked() }
753 }
754
755 #[inline]
756 #[track_caller]
757 fn strict_cast_from(value: $Src) -> Self {
758 match value.try_into() {
759 Ok(x) => x,
760 Err(_) => core::num::imp::overflow_panic::cast_integer()
761 }
762 }
763 }
764
765 #[unstable(feature = "integer_casts", issue = "157388")]
766 #[rustc_const_unstable(feature = "integer_casts", issue = "157388")]
767 const impl BoundedCastFromInt<$Src> for $Dst {
768 #[inline(always)]
769 fn wrapping_cast_from(value: $Src) -> Self {
770 value as Self
771 }
772
773 #[inline]
774 #[allow(unused_comparisons)]
775 #[allow(irrefutable_let_patterns)]
776 fn saturating_cast_from(value: $Src) -> Self {
777 if let Ok(x) = value.try_into() {
778 return x;
779 }
780
781 if value < 0 { <$Dst>::MIN } else { <$Dst>::MAX }
782 }
783 }
784 )*};
785}
786
787macro_rules! impl_all_int_casts {
788 ([$($Src:ty),*]) => {$(
789 impl_int_cast!($Src as [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize]);
790 )*};
791}
792
793impl_all_int_casts!([u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize]);