-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
TryFrom<integer> for bool #147400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TryFrom<integer> for bool #147400
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,63 +39,52 @@ impl_float_to_int!(f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i12 | |
| impl_float_to_int!(f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); | ||
| impl_float_to_int!(f128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); | ||
|
|
||
| // Conversion traits for primitive integer and float types | ||
| // Conversions T -> T are covered by a blanket impl and therefore excluded | ||
| // Some conversions from and to usize/isize are not implemented due to portability concerns | ||
| /// Implement `From<bool>` for integers | ||
| macro_rules! impl_from_bool { | ||
| ($($int:ty)*) => {$( | ||
| #[stable(feature = "from_bool", since = "1.28.0")] | ||
| #[rustc_const_unstable(feature = "const_convert", issue = "143773")] | ||
| impl const From<bool> for $int { | ||
| /// Converts from [`bool`] to | ||
| #[doc = concat!("[`", stringify!($int), "`]")] | ||
| /// , by turning `false` into `0` and `true` into `1`. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| #[doc = concat!("assert_eq!(", stringify!($int), "::from(false), 0);")] | ||
| /// | ||
| #[doc = concat!("assert_eq!(", stringify!($int), "::from(true), 1);")] | ||
| /// ``` | ||
| #[inline(always)] | ||
| fn from(b: bool) -> Self { | ||
| b as Self | ||
| } | ||
| } | ||
| )*} | ||
| } | ||
|
|
||
| // boolean -> integer | ||
| impl_from_bool!(u8 u16 u32 u64 u128 usize); | ||
| impl_from_bool!(i8 i16 i32 i64 i128 isize); | ||
|
|
||
| /// Implement `From<$small>` for `$large` | ||
| macro_rules! impl_from { | ||
| (bool => $Int:ty $(,)?) => { | ||
| impl_from!( | ||
| bool => $Int, | ||
| #[stable(feature = "from_bool", since = "1.28.0")], | ||
| concat!( | ||
| "Converts a [`bool`] to [`", stringify!($Int), "`] losslessly.\n", | ||
| "The resulting value is `0` for `false` and `1` for `true` values.\n", | ||
| "\n", | ||
| "# Examples\n", | ||
| "\n", | ||
| "```\n", | ||
| "assert_eq!(", stringify!($Int), "::from(true), 1);\n", | ||
| "assert_eq!(", stringify!($Int), "::from(false), 0);\n", | ||
| "```\n", | ||
| ), | ||
| ); | ||
| }; | ||
| ($Small:ty => $Large:ty, #[$attr:meta] $(,)?) => { | ||
| impl_from!( | ||
| $Small => $Large, | ||
| #[$attr], | ||
| concat!("Converts [`", stringify!($Small), "`] to [`", stringify!($Large), "`] losslessly."), | ||
| ); | ||
| }; | ||
| ($Small:ty => $Large:ty, #[$attr:meta], $doc:expr $(,)?) => { | ||
| ($small:ty => $large:ty, #[$attr:meta]) => { | ||
| #[$attr] | ||
| #[rustc_const_unstable(feature = "const_convert", issue = "143773")] | ||
| impl const From<$Small> for $Large { | ||
| // Rustdocs on the impl block show a "[+] show undocumented items" toggle. | ||
| // Rustdocs on functions do not. | ||
| #[doc = $doc] | ||
| impl const From<$small> for $large { | ||
| #[doc = concat!("Converts from [`", stringify!($small), "`] to [`", stringify!($large), "`] losslessly.")] | ||
| #[inline(always)] | ||
| fn from(small: $Small) -> Self { | ||
| fn from(small: $small) -> Self { | ||
| debug_assert!(<$large>::MIN as i128 <= <$small>::MIN as i128); | ||
| debug_assert!(<$small>::MAX as u128 <= <$large>::MAX as u128); | ||
| small as Self | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| // boolean -> integer | ||
| impl_from!(bool => u8); | ||
| impl_from!(bool => u16); | ||
| impl_from!(bool => u32); | ||
| impl_from!(bool => u64); | ||
| impl_from!(bool => u128); | ||
| impl_from!(bool => usize); | ||
| impl_from!(bool => i8); | ||
| impl_from!(bool => i16); | ||
| impl_from!(bool => i32); | ||
| impl_from!(bool => i64); | ||
| impl_from!(bool => i128); | ||
| impl_from!(bool => isize); | ||
|
|
||
| // unsigned integer -> unsigned integer | ||
| impl_from!(u8 => u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")]); | ||
| impl_from!(u8 => u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")]); | ||
|
|
@@ -338,12 +327,48 @@ macro_rules! impl_try_from_both_bounded { | |
| )*} | ||
| } | ||
|
|
||
| /// Implement `TryFrom<integer>` for `bool` | ||
| macro_rules! impl_try_from_integer_for_bool { | ||
| ($($int:ty)+) => {$( | ||
| #[stable(feature = "try_from", since = "1.34.0")] | ||
| #[rustc_const_unstable(feature = "const_convert", issue = "143773")] | ||
| impl const TryFrom<$int> for bool { | ||
| type Error = TryFromIntError; | ||
|
|
||
| /// Tries to create a bool from an integer type. | ||
| /// Returns an error if the integer is not 0 or 1. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| #[doc = concat!("assert_eq!(0_", stringify!($int), ".try_into(), Ok(false));")] | ||
| /// | ||
| #[doc = concat!("assert_eq!(1_", stringify!($int), ".try_into(), Ok(true));")] | ||
| /// | ||
| #[doc = concat!("assert!(<", stringify!($int), " as TryInto<bool>>::try_into(2).is_err());")] | ||
| /// ``` | ||
| #[inline] | ||
| fn try_from(i: $int) -> Result<Self, Self::Error> { | ||
| match i { | ||
| 0 => Ok(false), | ||
| 1 => Ok(true), | ||
| _ => Err(TryFromIntError(())), | ||
| } | ||
| } | ||
| } | ||
| )*} | ||
| } | ||
|
|
||
| macro_rules! rev { | ||
| ($mac:ident, $source:ty => $($target:ty),+) => {$( | ||
| $mac!($target => $source); | ||
| )*} | ||
| } | ||
|
|
||
| // integer -> bool | ||
| impl_try_from_integer_for_bool!(u128 u64 u32 u16 u8); | ||
| impl_try_from_integer_for_bool!(i128 i64 i32 i16 i8); | ||
|
Comment on lines
+369
to
+370
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this not have included
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question! I don't recall intentionally excluding those, and a cursory review brings up no reason for excluding them, so this seems to have been an oversight on my part. Feel free to open a new PR to add those.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would caution against trying to beta backport a stabilization of additional API surface |
||
|
|
||
| // unsigned integer -> unsigned integer | ||
| impl_try_from_upper_bounded!(u16 => u8); | ||
| impl_try_from_upper_bounded!(u32 => u8, u16); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used a feature gate with the wrong version. Fix in #154691
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.