-
Notifications
You must be signed in to change notification settings - Fork 13.4k
More const int functions #66884
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
Closed
Closed
More const int functions #66884
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
9a9cbd6
Make Option fns const
9999years 20db398
Make NonZero*::new const
9999years 09994af
Make overflowing_div and overflowing_rem const
9999years 9aa0a1f
Power-of-two int tests
9999years 60168a7
Power-of-two int tests
9999years 5e44a24
Make checked int fns const
9999years 17ab2c4
Make wrapping int fns const
9999years e749327
Make saturating int fns const
9999years 5909f54
Make Euclidean int fns const
9999years 70488cf
Make Option.transpose and Option.flatten const
9999years 48c9f1e
Make rem_euclid const
9999years 5744fe1
Revert: Make functional Option fns const
9999years 8c1f726
Revert: Make Option.flatten const
9999years 7248921
Delete bootstrap fns, factor out assert_same_const
9999years File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -183,10 +183,11 @@ impl<T> Option<T> { | |
/// ``` | ||
/// | ||
/// [`Some`]: #variant.Some | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"] | ||
#[inline] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn is_some(&self) -> bool { | ||
pub const fn is_some(&self) -> bool { | ||
match *self { | ||
Some(_) => true, | ||
None => false, | ||
|
@@ -206,11 +207,12 @@ impl<T> Option<T> { | |
/// ``` | ||
/// | ||
/// [`None`]: #variant.None | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[must_use = "if you intended to assert that this doesn't have a value, consider \ | ||
`.and_then(|| panic!(\"`Option` had a value when expected `None`\"))` instead"] | ||
#[inline] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn is_none(&self) -> bool { | ||
pub const fn is_none(&self) -> bool { | ||
!self.is_some() | ||
} | ||
|
||
|
@@ -267,9 +269,10 @@ impl<T> Option<T> { | |
/// let text_length: Option<usize> = text.as_ref().map(|s| s.len()); | ||
/// println!("still can print text: {:?}", text); | ||
/// ``` | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[inline] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn as_ref(&self) -> Option<&T> { | ||
pub const fn as_ref(&self) -> Option<&T> { | ||
match *self { | ||
Some(ref x) => Some(x), | ||
None => None, | ||
|
@@ -340,9 +343,10 @@ impl<T> Option<T> { | |
/// let x: Option<&str> = None; | ||
/// x.expect("the world is ending"); // panics with `the world is ending` | ||
/// ``` | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[inline] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn expect(self, msg: &str) -> T { | ||
pub const fn expect(self, msg: &str) -> T { | ||
match self { | ||
Some(val) => val, | ||
None => expect_failed(msg), | ||
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.
|
||
|
@@ -396,9 +400,10 @@ impl<T> Option<T> { | |
/// assert_eq!(Some("car").unwrap_or("bike"), "car"); | ||
/// assert_eq!(None.unwrap_or("bike"), "bike"); | ||
/// ``` | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[inline] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn unwrap_or(self, default: T) -> T { | ||
pub const fn unwrap_or(self, default: T) -> T { | ||
match self { | ||
Some(x) => x, | ||
None => default, | ||
|
@@ -519,9 +524,10 @@ impl<T> Option<T> { | |
/// let x: Option<&str> = None; | ||
/// assert_eq!(x.ok_or(0), Err(0)); | ||
/// ``` | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[inline] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn ok_or<E>(self, err: E) -> Result<T, E> { | ||
pub const fn ok_or<E>(self, err: E) -> Result<T, E> { | ||
match self { | ||
Some(v) => Ok(v), | ||
None => Err(err), | ||
|
@@ -624,9 +630,10 @@ impl<T> Option<T> { | |
/// let y: Option<&str> = None; | ||
/// assert_eq!(x.and(y), None); | ||
/// ``` | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[inline] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn and<U>(self, optb: Option<U>) -> Option<U> { | ||
pub const fn and<U>(self, optb: Option<U>) -> Option<U> { | ||
match self { | ||
Some(_) => optb, | ||
None => None, | ||
|
@@ -724,9 +731,10 @@ impl<T> Option<T> { | |
/// let y = None; | ||
/// assert_eq!(x.or(y), None); | ||
/// ``` | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[inline] | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn or(self, optb: Option<T>) -> Option<T> { | ||
pub const fn or(self, optb: Option<T>) -> Option<T> { | ||
match self { | ||
Some(_) => self, | ||
None => optb, | ||
|
@@ -779,9 +787,10 @@ impl<T> Option<T> { | |
/// let y: Option<u32> = None; | ||
/// assert_eq!(x.xor(y), None); | ||
/// ``` | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
#[inline] | ||
#[stable(feature = "option_xor", since = "1.37.0")] | ||
pub fn xor(self, optb: Option<T>) -> Option<T> { | ||
pub const fn xor(self, optb: Option<T>) -> Option<T> { | ||
match (self, optb) { | ||
(Some(a), None) => Some(a), | ||
(None, Some(b)) => Some(b), | ||
|
@@ -1172,14 +1181,14 @@ impl<T, E> Option<Result<T, E>> { | |
/// ``` | ||
#[inline] | ||
#[stable(feature = "transpose_result", since = "1.33.0")] | ||
pub fn transpose(self) -> Result<Option<T>, E> { | ||
#[rustc_const_unstable(feature = "const_option_match")] | ||
pub const fn transpose(self) -> Result<Option<T>, E> { | ||
match self { | ||
Some(Ok(x)) => Ok(Some(x)), | ||
Some(Err(e)) => Err(e), | ||
None => Ok(None), | ||
} | ||
} | ||
} | ||
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. you lost a closing bracket |
||
|
||
// This is a separate function to reduce the code size of .expect() itself. | ||
#[inline(never)] | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/// Given a block of const bindings, asserts that their values (calculated at runtime) are the | ||
/// same as their values (calculated at compile-time). | ||
macro_rules! assert_same_const { | ||
($(const $ident:ident: $ty:ty = $exp:expr;)+) => { | ||
$(const $ident: $ty = $exp;)+ | ||
|
||
pub fn main() { | ||
$({ | ||
// Assign the expr to a variable at runtime; otherwise, the argument is | ||
// calculated at compile-time, making the test useless. | ||
let tmp = $exp; | ||
assert_eq!(tmp, $ident); | ||
})+ | ||
} | ||
} | ||
} | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// run-pass | ||
#![feature(const_int_checked)] | ||
|
||
macro_rules! assert_same_const { | ||
($(const $ident:ident: $ty:ty = $exp:expr;)+) => { | ||
$(const $ident: $ty = $exp;)+ | ||
|
||
pub fn main() { | ||
$(assert_eq!($exp, $ident);)+ | ||
9999years marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
|
||
assert_same_const! { | ||
const CHECKED_ADD_I32_A: Option<i32> = 5i32.checked_add(2); | ||
const CHECKED_ADD_I8_A: Option<i8> = 127i8.checked_add(2); | ||
const CHECKED_ADD_U8_A: Option<u8> = 255u8.checked_add(2); | ||
|
||
const CHECKED_SUB_I32_A: Option<i32> = 5i32.checked_sub(2); | ||
const CHECKED_SUB_I8_A: Option<i8> = (-127 as i8).checked_sub(2); | ||
const CHECKED_SUB_U8_A: Option<u8> = 1u8.checked_sub(2); | ||
|
||
const CHECKED_MUL_I32_A: Option<i32> = 5i32.checked_mul(7777); | ||
const CHECKED_MUL_I8_A: Option<i8> = (-127 as i8).checked_mul(-99); | ||
const CHECKED_MUL_U8_A: Option<u8> = 1u8.checked_mul(3); | ||
|
||
// Needs intrinsics::unchecked_div. | ||
// const CHECKED_DIV_I32_A: Option<i32> = 5i32.checked_div(7777); | ||
// const CHECKED_DIV_I8_A: Option<i8> = (-127 as i8).checked_div(-99); | ||
// const CHECKED_DIV_U8_A: Option<u8> = 1u8.checked_div(3); | ||
|
||
// Needs intrinsics::unchecked_rem. | ||
// const CHECKED_REM_I32_A: Option<i32> = 5i32.checked_rem(7777); | ||
// const CHECKED_REM_I8_A: Option<i8> = (-127 as i8).checked_rem(-99); | ||
// const CHECKED_REM_U8_A: Option<u8> = 1u8.checked_rem(3); | ||
// const CHECKED_REM_U8_B: Option<u8> = 1u8.checked_rem(0); | ||
|
||
const CHECKED_NEG_I32_A: Option<i32> = 5i32.checked_neg(); | ||
const CHECKED_NEG_I8_A: Option<i8> = (-127 as i8).checked_neg(); | ||
const CHECKED_NEG_U8_A: Option<u8> = 1u8.checked_neg(); | ||
const CHECKED_NEG_U8_B: Option<u8> = u8::min_value().checked_neg(); | ||
|
||
const CHECKED_SHL_I32_A: Option<i32> = 5i32.checked_shl(77777); | ||
const CHECKED_SHL_I8_A: Option<i8> = (-127 as i8).checked_shl(2); | ||
const CHECKED_SHL_U8_A: Option<u8> = 1u8.checked_shl(8); | ||
const CHECKED_SHL_U8_B: Option<u8> = 1u8.checked_shl(0); | ||
|
||
const CHECKED_SHR_I32_A: Option<i32> = 5i32.checked_shr(77777); | ||
const CHECKED_SHR_I8_A: Option<i8> = (-127 as i8).checked_shr(2); | ||
const CHECKED_SHR_U8_A: Option<u8> = 1u8.checked_shr(8); | ||
const CHECKED_SHR_U8_B: Option<u8> = 1u8.checked_shr(0); | ||
|
||
const CHECKED_ABS_I32_A: Option<i32> = 5i32.checked_abs(); | ||
const CHECKED_ABS_I8_A: Option<i8> = (-127 as i8).checked_abs(); | ||
const CHECKED_ABS_I8_B: Option<i8> = 1i8.checked_abs(); | ||
const CHECKED_ABS_I8_C: Option<i8> = i8::min_value().checked_abs(); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// run-pass | ||
// aux-build:const_assert_lib.rs | ||
use const_assert_lib::assert_same_const; | ||
|
||
#![feature(const_int_euclidean)] | ||
#![feature(saturating_neg)] | ||
|
||
assert_same_const! { | ||
const CHECKED_DIV_I32_A: Option<i32> = 5i32.checked_div_euclid(7777); | ||
const CHECKED_DIV_I8_A: Option<i8> = (-127 as i8).checked_div_euclid(-99); | ||
const CHECKED_DIV_I8_B: Option<i8> = (-127 as i8).checked_div_euclid(1); | ||
const CHECKED_DIV_I8_C: Option<i8> = i8::min_value().checked_div_euclid(-1); | ||
const CHECKED_DIV_U8_A: Option<u8> = 1u8.checked_div_euclid(3); | ||
|
||
const CHECKED_REM_I32_A: Option<i32> = 5i32.checked_rem_euclid(7777); | ||
const CHECKED_REM_I8_A: Option<i8> = (-127 as i8).checked_rem_euclid(-99); | ||
const CHECKED_REM_I8_B: Option<i8> = (-127 as i8).checked_rem_euclid(0); | ||
const CHECKED_REM_I8_C: Option<i8> = i8::min_value().checked_rem_euclid(-1); | ||
const CHECKED_REM_U8_A: Option<u8> = 1u8.checked_rem_euclid(3); | ||
|
||
const WRAPPING_DIV_I32_A: i32 = 5i32.wrapping_div_euclid(7777); | ||
const WRAPPING_DIV_I8_A: i8 = (-127 as i8).wrapping_div_euclid(-99); | ||
const WRAPPING_DIV_I8_B: i8 = (-127 as i8).wrapping_div_euclid(1); | ||
const WRAPPING_DIV_I8_C: i8 = i8::min_value().wrapping_div_euclid(-1); | ||
const WRAPPING_DIV_U8_A: u8 = 1u8.wrapping_div_euclid(3); | ||
|
||
const WRAPPING_REM_I32_A: i32 = 5i32.wrapping_rem_euclid(7777); | ||
const WRAPPING_REM_I8_A: i8 = (-127 as i8).wrapping_rem_euclid(-99); | ||
const WRAPPING_REM_I8_B: i8 = (-127 as i8).wrapping_rem_euclid(1); | ||
const WRAPPING_REM_I8_C: i8 = i8::min_value().wrapping_rem_euclid(-1); | ||
const WRAPPING_REM_U8_A: u8 = 1u8.wrapping_rem_euclid(3); | ||
|
||
const OVERFLOWING_DIV_I32_A: (i32, bool) = 5i32.overflowing_div_euclid(7777); | ||
const OVERFLOWING_DIV_I8_A: (i8, bool) = (-127 as i8).overflowing_div_euclid(-99); | ||
const OVERFLOWING_DIV_I8_B: (i8, bool) = (-127 as i8).overflowing_div_euclid(1); | ||
const OVERFLOWING_DIV_I8_C: (i8, bool) = i8::min_value().overflowing_div_euclid(-1); | ||
const OVERFLOWING_DIV_U8_A: (u8, bool) = 1u8.overflowing_div_euclid(3); | ||
|
||
const OVERFLOWING_REM_I32_A: (i32, bool) = 5i32.overflowing_rem_euclid(7777); | ||
const OVERFLOWING_REM_I8_A: (i8, bool) = (-127 as i8).overflowing_rem_euclid(-99); | ||
const OVERFLOWING_REM_I8_B: (i8, bool) = (-127 as i8).overflowing_rem_euclid(1); | ||
const OVERFLOWING_REM_I8_C: (i8, bool) = i8::min_value().overflowing_rem_euclid(-1); | ||
const OVERFLOWING_REM_U8_A: (u8, bool) = 1u8.overflowing_rem_euclid(3); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// run-pass | ||
// aux-build:const_assert_lib.rs | ||
use const_assert_lib::assert_same_const; | ||
|
||
#![feature(const_int_nonzero)] | ||
|
||
use std::num::{ | ||
NonZeroI8, | ||
NonZeroU8, | ||
NonZeroI32, | ||
NonZeroUsize, | ||
}; | ||
|
||
assert_same_const! { | ||
const NON_ZERO_NEW_1: Option<NonZeroI8> = NonZeroI8::new(1); | ||
const NON_ZERO_NEW_2: Option<NonZeroI8> = NonZeroI8::new(0); | ||
const NON_ZERO_NEW_3: Option<NonZeroI8> = NonZeroI8::new(-38); | ||
const NON_ZERO_NEW_4: Option<NonZeroU8> = NonZeroU8::new(1); | ||
const NON_ZERO_NEW_5: Option<NonZeroU8> = NonZeroU8::new(0); | ||
const NON_ZERO_NEW_6: Option<NonZeroI32> = NonZeroI32::new(1); | ||
const NON_ZERO_NEW_7: Option<NonZeroI32> = NonZeroI32::new(0); | ||
const NON_ZERO_NEW_8: Option<NonZeroI32> = NonZeroI32::new(-38); | ||
const NON_ZERO_NEW_9: Option<NonZeroUsize> = NonZeroUsize::new(1); | ||
const NON_ZERO_NEW_10: Option<NonZeroUsize> = NonZeroUsize::new(0); | ||
|
||
// Option::unwrap isn't supported in const yet, so we use new_unchecked. | ||
const NON_ZERO_GET_1: i8 = unsafe { NonZeroI8::new_unchecked(1) }.get(); | ||
const NON_ZERO_GET_2: i8 = unsafe { NonZeroI8::new_unchecked(-38) }.get(); | ||
const NON_ZERO_GET_3: u8 = unsafe { NonZeroU8::new_unchecked(1) }.get(); | ||
const NON_ZERO_GET_4: i32 = unsafe { NonZeroI32::new_unchecked(1) }.get(); | ||
const NON_ZERO_GET_5: i32 = unsafe { NonZeroI32::new_unchecked(-38) }.get(); | ||
const NON_ZERO_GET_6: usize = unsafe { NonZeroUsize::new_unchecked(1) }.get(); | ||
|
||
const NON_ZERO_NEW_UNCHECKED_1: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(1) }; | ||
const NON_ZERO_NEW_UNCHECKED_2: NonZeroI8 = unsafe { NonZeroI8::new_unchecked(-38) }; | ||
const NON_ZERO_NEW_UNCHECKED_3: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(1) }; | ||
const NON_ZERO_NEW_UNCHECKED_4: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(1) }; | ||
const NON_ZERO_NEW_UNCHECKED_5: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(-38) }; | ||
const NON_ZERO_NEW_UNCHECKED_6: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(1) }; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,15 @@ | ||
// run-pass | ||
// #![feature(const_int_pow)] | ||
#![feature(wrapping_next_power_of_two)] | ||
|
||
const IS_POWER_OF_TWO_A: bool = 0u32.is_power_of_two(); | ||
const IS_POWER_OF_TWO_B: bool = 32u32.is_power_of_two(); | ||
const IS_POWER_OF_TWO_C: bool = 33u32.is_power_of_two(); | ||
const IS_POWER_OF_TWO_D: bool = 3u8.is_power_of_two(); | ||
|
||
fn main() { | ||
assert!(!IS_POWER_OF_TWO_A); | ||
assert!(IS_POWER_OF_TWO_B); | ||
assert!(!IS_POWER_OF_TWO_C); | ||
assert!(!IS_POWER_OF_TWO_D); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.