diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a2ab85e64baa1..5c47ce9c2781e 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -128,6 +128,7 @@ #![feature(maybe_uninit_slice)] #![feature(external_doc)] #![feature(associated_type_bounds)] +#![feature(const_if_match)] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 6c864f74b1f14..285fee71c0a68 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -70,10 +70,11 @@ assert_eq!(size_of::>(), size_of::<", s /// Creates a non-zero if the given value is not zero. #[$stability] #[inline] - pub fn new(n: $Int) -> Option { + #[rustc_const_unstable(feature = "const_int_nonzero")] + pub const fn new(n: $Int) -> Option { if n != 0 { // SAFETY: we just checked that there's no `0` - Some(unsafe { Self(n) }) + Some(unsafe { $Ty(n) }) } else { None } @@ -644,7 +645,8 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_add(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_add(self, rhs: Self) -> Option { let (a, b) = self.overflowing_add(rhs); if b {None} else {Some(a)} } @@ -668,7 +670,8 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_sub(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_sub(self, rhs: Self) -> Option { let (a, b) = self.overflowing_sub(rhs); if b {None} else {Some(a)} } @@ -692,7 +695,8 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_mul(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_mul(self, rhs: Self) -> Option { let (a, b) = self.overflowing_mul(rhs); if b {None} else {Some(a)} } @@ -717,7 +721,8 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_div(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_div(self, rhs: Self) -> Option { if rhs == 0 || (self == Self::min_value() && rhs == -1) { None } else { @@ -745,7 +750,8 @@ assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_div_euclid(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn checked_div_euclid(self, rhs: Self) -> Option { if rhs == 0 || (self == Self::min_value() && rhs == -1) { None } else { @@ -803,7 +809,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_rem_euclid(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn checked_rem_euclid(self, rhs: Self) -> Option { if rhs == 0 || (self == Self::min_value() && rhs == -1) { None } else { @@ -828,7 +835,8 @@ $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] #[inline] - pub fn checked_neg(self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_neg(self) -> Option { let (a, b) = self.overflowing_neg(); if b {None} else {Some(a)} } @@ -851,12 +859,14 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_shl(self, rhs: u32) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_shl(self, rhs: u32) -> Option { let (a, b) = self.overflowing_shl(rhs); if b {None} else {Some(a)} } } + doc_comment! { concat!("Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is larger than or equal to the number of bits in `self`. @@ -874,7 +884,8 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_shr(self, rhs: u32) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_shr(self, rhs: u32) -> Option { let (a, b) = self.overflowing_shr(rhs); if b {None} else {Some(a)} } @@ -897,7 +908,8 @@ $EndFeature, " ```"), #[stable(feature = "no_panic_abs", since = "1.13.0")] #[inline] - pub fn checked_abs(self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_abs(self) -> Option { if self.is_negative() { self.checked_neg() } else { @@ -1020,8 +1032,11 @@ $EndFeature, " ```"), #[unstable(feature = "saturating_neg", issue = "59983")] + #[rustc_const_unstable(feature = "const_saturating_int_methods")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] #[inline] - pub fn saturating_neg(self) -> Self { + pub const fn saturating_neg(self) -> Self { intrinsics::saturating_sub(0, self) } } @@ -1046,8 +1061,11 @@ $EndFeature, " ```"), #[unstable(feature = "saturating_neg", issue = "59983")] + #[rustc_const_unstable(feature = "const_saturating_int_methods")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] #[inline] - pub fn saturating_abs(self) -> Self { + pub const fn saturating_abs(self) -> Self { if self.is_negative() { self.saturating_neg() } else { @@ -1076,14 +1094,18 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn saturating_mul(self, rhs: Self) -> Self { - self.checked_mul(rhs).unwrap_or_else(|| { - if (self < 0) == (rhs < 0) { - Self::max_value() - } else { - Self::min_value() - } - }) + #[rustc_const_unstable(feature = "const_int_saturating")] + pub const fn saturating_mul(self, rhs: Self) -> Self { + match self.checked_mul(rhs) { + Some(r) => r, + None => { + if (self < 0) == (rhs < 0) { + Self::max_value() + } else { + Self::min_value() + } + }, + } } } @@ -1212,7 +1234,8 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_div(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_wrapping")] + pub const fn wrapping_div(self, rhs: Self) -> Self { self.overflowing_div(rhs).0 } } @@ -1241,7 +1264,8 @@ assert_eq!((-128i8).wrapping_div_euclid(-1), -128); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_div_euclid(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn wrapping_div_euclid(self, rhs: Self) -> Self { self.overflowing_div_euclid(rhs).0 } } @@ -1271,7 +1295,8 @@ $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_rem(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_wrapping")] + pub const fn wrapping_rem(self, rhs: Self) -> Self { self.overflowing_rem(rhs).0 } } @@ -1299,7 +1324,8 @@ assert_eq!((-128i8).wrapping_rem_euclid(-1), 0); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_rem_euclid(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self { self.overflowing_rem_euclid(rhs).0 } } @@ -1580,7 +1606,8 @@ $EndFeature, " #[stable(feature = "wrapping", since = "1.7.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + #[rustc_const_unstable(feature = "const_int_overflowing")] + pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { if self == Self::min_value() && rhs == -1 { (self, true) } else { @@ -1614,7 +1641,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringi #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { if self == Self::min_value() && rhs == -1 { (self, true) } else { @@ -1648,7 +1676,8 @@ $EndFeature, " #[stable(feature = "wrapping", since = "1.7.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + #[rustc_const_unstable(feature = "const_int_overflowing")] + pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { if self == Self::min_value() && rhs == -1 { (0, true) } else { @@ -1657,7 +1686,6 @@ $EndFeature, " } } - doc_comment! { concat!("Overflowing Euclidean remainder. Calculates `self.rem_euclid(rhs)`. @@ -1682,7 +1710,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true)); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { if self == Self::min_value() && rhs == -1 { (0, true) } else { @@ -1691,7 +1720,6 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true)); } } - doc_comment! { concat!("Negates self, overflowing if this is equal to the minimum value. @@ -1922,7 +1950,8 @@ assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2 without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub fn div_euclid(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn div_euclid(self, rhs: Self) -> Self { let q = self / rhs; if self % rhs < 0 { return if rhs > 0 { q - 1 } else { q + 1 } @@ -1931,7 +1960,6 @@ assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2 } } - doc_comment! { concat!("Calculates the least nonnegative remainder of `self (mod rhs)`. @@ -1961,7 +1989,8 @@ assert_eq!((-a).rem_euclid(-b), 1); without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub fn rem_euclid(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn rem_euclid(self, rhs: Self) -> Self { let r = self % rhs; if r < 0 { if rhs < 0 { @@ -2736,7 +2765,8 @@ assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_add(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_add(self, rhs: Self) -> Option { let (a, b) = self.overflowing_add(rhs); if b {None} else {Some(a)} } @@ -2758,7 +2788,8 @@ assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_sub(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_sub(self, rhs: Self) -> Option { let (a, b) = self.overflowing_sub(rhs); if b {None} else {Some(a)} } @@ -2780,7 +2811,8 @@ assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", $EndFe #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_mul(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_mul(self, rhs: Self) -> Option { let (a, b) = self.overflowing_mul(rhs); if b {None} else {Some(a)} } @@ -2802,7 +2834,8 @@ assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_div(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_div(self, rhs: Self) -> Option { match rhs { 0 => None, // SAFETY: div by zero has been checked above and unsigned types have no other @@ -2828,7 +2861,8 @@ assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_div_euclid(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn checked_div_euclid(self, rhs: Self) -> Option { if rhs == 0 { None } else { @@ -2837,7 +2871,6 @@ assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None); } } - doc_comment! { concat!("Checked integer remainder. Computes `self % rhs`, returning `None` if `rhs == 0`. @@ -2854,7 +2887,8 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, " #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_rem(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_rem(self, rhs: Self) -> Option { if rhs == 0 { None } else { @@ -2881,7 +2915,8 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_rem_euclid(self, rhs: Self) -> Option { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn checked_rem_euclid(self, rhs: Self) -> Option { if rhs == 0 { None } else { @@ -2906,7 +2941,8 @@ assert_eq!(1", stringify!($SelfT), ".checked_neg(), None);", $EndFeature, " ```"), #[stable(feature = "wrapping", since = "1.7.0")] #[inline] - pub fn checked_neg(self) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_neg(self) -> Option { let (a, b) = self.overflowing_neg(); if b {None} else {Some(a)} } @@ -2928,7 +2964,8 @@ assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_shl(self, rhs: u32) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_shl(self, rhs: u32) -> Option { let (a, b) = self.overflowing_shl(rhs); if b {None} else {Some(a)} } @@ -2950,7 +2987,8 @@ assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn checked_shr(self, rhs: u32) -> Option { + #[rustc_const_unstable(feature = "const_int_checked")] + pub const fn checked_shr(self, rhs: u32) -> Option { let (a, b) = self.overflowing_shr(rhs); if b {None} else {Some(a)} } @@ -3059,7 +3097,8 @@ assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($Se #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn saturating_mul(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_saturating")] + pub const fn saturating_mul(self, rhs: Self) -> Self { self.checked_mul(rhs).unwrap_or(Self::max_value()) } } @@ -3154,7 +3193,7 @@ $EndFeature, " #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] #[must_use = "this returns the result of the operation, \ - without modifying the original"] + without modifying the original"] #[inline] pub const fn wrapping_mul(self, rhs: Self) -> Self { intrinsics::wrapping_mul(self, rhs) @@ -3178,7 +3217,8 @@ Basic usage: #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_div(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_wrapping")] + pub const fn wrapping_div(self, rhs: Self) -> Self { self / rhs } } @@ -3204,7 +3244,8 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_div_euclid(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn wrapping_div_euclid(self, rhs: Self) -> Self { self / rhs } } @@ -3228,7 +3269,8 @@ Basic usage: #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_rem(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_wrapping")] + pub const fn wrapping_rem(self, rhs: Self) -> Self { self % rhs } } @@ -3255,7 +3297,8 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub fn wrapping_rem_euclid(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self { self % rhs } } @@ -3472,7 +3515,7 @@ $EndFeature, " #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")] #[must_use = "this returns the result of the operation, \ - without modifying the original"] + without modifying the original"] #[inline] pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) { let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT); @@ -3502,7 +3545,8 @@ Basic usage #[stable(feature = "wrapping", since = "1.7.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + #[rustc_const_unstable(feature = "const_int_overflowing")] + pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { (self / rhs, false) } } @@ -3533,7 +3577,8 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false)); #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { (self / rhs, false) } } @@ -3561,7 +3606,8 @@ Basic usage #[stable(feature = "wrapping", since = "1.7.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + #[rustc_const_unstable(feature = "const_int_overflowing")] + pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { (self % rhs, false) } } @@ -3592,7 +3638,8 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false)); #[stable(feature = "euclidean_division", since = "1.38.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { (self % rhs, false) } } @@ -3738,7 +3785,7 @@ Basic usage: ```"), #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "this returns the result of the operation, \ - without modifying the original"] + without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] pub fn pow(self, mut exp: u32) -> Self { @@ -3787,12 +3834,12 @@ assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub fn div_euclid(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn div_euclid(self, rhs: Self) -> Self { self / rhs } } - doc_comment! { concat!("Calculates the least remainder of `self (mod rhs)`. @@ -3816,7 +3863,8 @@ assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer without modifying the original"] #[inline] #[rustc_inherit_overflow_checks] - pub fn rem_euclid(self, rhs: Self) -> Self { + #[rustc_const_unstable(feature = "const_int_euclidean")] + pub const fn rem_euclid(self, rhs: Self) -> Self { self % rhs } } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 2066a484dac80..ad404307cc40a 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -183,10 +183,11 @@ impl Option { /// ``` /// /// [`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 Option { /// ``` /// /// [`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 Option { /// let text_length: Option = 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 Option { /// 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), @@ -396,9 +400,10 @@ impl Option { /// 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 Option { /// 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(self, err: E) -> Result { + pub const fn ok_or(self, err: E) -> Result { match self { Some(v) => Ok(v), None => Err(err), @@ -624,9 +630,10 @@ impl Option { /// 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(self, optb: Option) -> Option { + pub const fn and(self, optb: Option) -> Option { match self { Some(_) => optb, None => None, @@ -724,9 +731,10 @@ impl Option { /// 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) -> Option { + pub const fn or(self, optb: Option) -> Option { match self { Some(_) => self, None => optb, @@ -779,9 +787,10 @@ impl Option { /// let y: Option = 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) -> Option { + pub const fn xor(self, optb: Option) -> Option { match (self, optb) { (Some(a), None) => Some(a), (None, Some(b)) => Some(b), @@ -1172,14 +1181,14 @@ impl Option> { /// ``` #[inline] #[stable(feature = "transpose_result", since = "1.33.0")] - pub fn transpose(self) -> Result, E> { + #[rustc_const_unstable(feature = "const_option_match")] + pub const fn transpose(self) -> Result, E> { match self { Some(Ok(x)) => Ok(Some(x)), Some(Err(e)) => Err(e), None => Ok(None), } } -} // This is a separate function to reduce the code size of .expect() itself. #[inline(never)] diff --git a/src/test/ui/consts/auxiliary/const_assert_lib.rs b/src/test/ui/consts/auxiliary/const_assert_lib.rs new file mode 100644 index 0000000000000..f6ca2d65f080e --- /dev/null +++ b/src/test/ui/consts/auxiliary/const_assert_lib.rs @@ -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); + })+ + } + } +} + diff --git a/src/test/ui/consts/const-int-checked.rs b/src/test/ui/consts/const-int-checked.rs new file mode 100644 index 0000000000000..de9d29b7fa672 --- /dev/null +++ b/src/test/ui/consts/const-int-checked.rs @@ -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);)+ + } + } +} + +assert_same_const! { + const CHECKED_ADD_I32_A: Option = 5i32.checked_add(2); + const CHECKED_ADD_I8_A: Option = 127i8.checked_add(2); + const CHECKED_ADD_U8_A: Option = 255u8.checked_add(2); + + const CHECKED_SUB_I32_A: Option = 5i32.checked_sub(2); + const CHECKED_SUB_I8_A: Option = (-127 as i8).checked_sub(2); + const CHECKED_SUB_U8_A: Option = 1u8.checked_sub(2); + + const CHECKED_MUL_I32_A: Option = 5i32.checked_mul(7777); + const CHECKED_MUL_I8_A: Option = (-127 as i8).checked_mul(-99); + const CHECKED_MUL_U8_A: Option = 1u8.checked_mul(3); + + // Needs intrinsics::unchecked_div. + // const CHECKED_DIV_I32_A: Option = 5i32.checked_div(7777); + // const CHECKED_DIV_I8_A: Option = (-127 as i8).checked_div(-99); + // const CHECKED_DIV_U8_A: Option = 1u8.checked_div(3); + + // Needs intrinsics::unchecked_rem. + // const CHECKED_REM_I32_A: Option = 5i32.checked_rem(7777); + // const CHECKED_REM_I8_A: Option = (-127 as i8).checked_rem(-99); + // const CHECKED_REM_U8_A: Option = 1u8.checked_rem(3); + // const CHECKED_REM_U8_B: Option = 1u8.checked_rem(0); + + const CHECKED_NEG_I32_A: Option = 5i32.checked_neg(); + const CHECKED_NEG_I8_A: Option = (-127 as i8).checked_neg(); + const CHECKED_NEG_U8_A: Option = 1u8.checked_neg(); + const CHECKED_NEG_U8_B: Option = u8::min_value().checked_neg(); + + const CHECKED_SHL_I32_A: Option = 5i32.checked_shl(77777); + const CHECKED_SHL_I8_A: Option = (-127 as i8).checked_shl(2); + const CHECKED_SHL_U8_A: Option = 1u8.checked_shl(8); + const CHECKED_SHL_U8_B: Option = 1u8.checked_shl(0); + + const CHECKED_SHR_I32_A: Option = 5i32.checked_shr(77777); + const CHECKED_SHR_I8_A: Option = (-127 as i8).checked_shr(2); + const CHECKED_SHR_U8_A: Option = 1u8.checked_shr(8); + const CHECKED_SHR_U8_B: Option = 1u8.checked_shr(0); + + const CHECKED_ABS_I32_A: Option = 5i32.checked_abs(); + const CHECKED_ABS_I8_A: Option = (-127 as i8).checked_abs(); + const CHECKED_ABS_I8_B: Option = 1i8.checked_abs(); + const CHECKED_ABS_I8_C: Option = i8::min_value().checked_abs(); +} diff --git a/src/test/ui/consts/const-int-euclidean.rs b/src/test/ui/consts/const-int-euclidean.rs new file mode 100644 index 0000000000000..6b4ce6df01fe1 --- /dev/null +++ b/src/test/ui/consts/const-int-euclidean.rs @@ -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 = 5i32.checked_div_euclid(7777); + const CHECKED_DIV_I8_A: Option = (-127 as i8).checked_div_euclid(-99); + const CHECKED_DIV_I8_B: Option = (-127 as i8).checked_div_euclid(1); + const CHECKED_DIV_I8_C: Option = i8::min_value().checked_div_euclid(-1); + const CHECKED_DIV_U8_A: Option = 1u8.checked_div_euclid(3); + + const CHECKED_REM_I32_A: Option = 5i32.checked_rem_euclid(7777); + const CHECKED_REM_I8_A: Option = (-127 as i8).checked_rem_euclid(-99); + const CHECKED_REM_I8_B: Option = (-127 as i8).checked_rem_euclid(0); + const CHECKED_REM_I8_C: Option = i8::min_value().checked_rem_euclid(-1); + const CHECKED_REM_U8_A: Option = 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); +} diff --git a/src/test/ui/consts/const-int-nonzero.rs b/src/test/ui/consts/const-int-nonzero.rs new file mode 100644 index 0000000000000..049ab36090471 --- /dev/null +++ b/src/test/ui/consts/const-int-nonzero.rs @@ -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::new(1); + const NON_ZERO_NEW_2: Option = NonZeroI8::new(0); + const NON_ZERO_NEW_3: Option = NonZeroI8::new(-38); + const NON_ZERO_NEW_4: Option = NonZeroU8::new(1); + const NON_ZERO_NEW_5: Option = NonZeroU8::new(0); + const NON_ZERO_NEW_6: Option = NonZeroI32::new(1); + const NON_ZERO_NEW_7: Option = NonZeroI32::new(0); + const NON_ZERO_NEW_8: Option = NonZeroI32::new(-38); + const NON_ZERO_NEW_9: Option = NonZeroUsize::new(1); + const NON_ZERO_NEW_10: Option = 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) }; +} diff --git a/src/test/ui/consts/const-int-overflowing-rpass.rs b/src/test/ui/consts/const-int-overflowing-rpass.rs index 9be87a6447cda..7b1a161348568 100644 --- a/src/test/ui/consts/const-int-overflowing-rpass.rs +++ b/src/test/ui/consts/const-int-overflowing-rpass.rs @@ -1,4 +1,5 @@ // run-pass +#![feature(const_int_overflowing)] const ADD_A: (u32, bool) = 5u32.overflowing_add(2); const ADD_B: (u32, bool) = u32::max_value().overflowing_add(1); @@ -22,6 +23,18 @@ const ABS_POS: (i32, bool) = 10i32.overflowing_abs(); const ABS_NEG: (i32, bool) = (-10i32).overflowing_abs(); const ABS_MIN: (i32, bool) = i32::min_value().overflowing_abs(); +const DIV_A: (i8, bool) = 8i8.overflowing_div(2); +const DIV_B: (i8, bool) = 8i8.overflowing_div(3); +const DIV_C: (i8, bool) = i8::min_value().overflowing_div(-1i8); +const DIV_D: (u8, bool) = 8u8.overflowing_div(2); +const DIV_E: (u8, bool) = 8u8.overflowing_div(3); + +const REM_A: (i8, bool) = 8i8.overflowing_rem(2); +const REM_B: (i8, bool) = 8i8.overflowing_rem(3); +const REM_C: (i8, bool) = i8::min_value().overflowing_rem(-1i8); +const REM_D: (u8, bool) = 8u8.overflowing_rem(2); +const REM_E: (u8, bool) = 8u8.overflowing_rem(3); + fn main() { assert_eq!(ADD_A, (7, false)); assert_eq!(ADD_B, (0, true)); @@ -44,4 +57,16 @@ fn main() { assert_eq!(ABS_POS, (10, false)); assert_eq!(ABS_NEG, (10, false)); assert_eq!(ABS_MIN, (i32::min_value(), true)); + + assert_eq!(DIV_A, (4i8, false)); + assert_eq!(DIV_B, (2i8, false)); + assert_eq!(DIV_C, (i8::min_value(), true)); + assert_eq!(DIV_D, (4u8, false)); + assert_eq!(DIV_E, (2u8, false)); + + assert_eq!(REM_A, (0i8, false)); + assert_eq!(REM_B, (2i8, false)); + assert_eq!(REM_C, (0i8, true)); + assert_eq!(REM_D, (0u8, false)); + assert_eq!(REM_E, (2u8, false)); } diff --git a/src/test/ui/consts/const-int-pow-rpass.rs b/src/test/ui/consts/const-int-pow-rpass.rs index 8e84a900605f5..26fb40650d451 100644 --- a/src/test/ui/consts/const-int-pow-rpass.rs +++ b/src/test/ui/consts/const-int-pow-rpass.rs @@ -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); } diff --git a/src/test/ui/consts/const-int-saturating-arith.rs b/src/test/ui/consts/const-int-saturating-arith.rs index d0a3eccd17763..fae273ea20bc8 100644 --- a/src/test/ui/consts/const-int-saturating-arith.rs +++ b/src/test/ui/consts/const-int-saturating-arith.rs @@ -1,34 +1,88 @@ // run-pass #![feature(const_saturating_int_methods)] +#![feature(const_int_saturating)] +#![feature(saturating_neg)] -const INT_U32_NO: u32 = (42 as u32).saturating_add(2); -const INT_U32: u32 = u32::max_value().saturating_add(1); -const INT_U128: u128 = u128::max_value().saturating_add(1); -const INT_I128: i128 = i128::max_value().saturating_add(1); -const INT_I128_NEG: i128 = i128::min_value().saturating_add(-1); - -const INT_U32_NO_SUB: u32 = (42 as u32).saturating_sub(2); -const INT_U32_SUB: u32 = (1 as u32).saturating_sub(2); -const INT_I32_NO_SUB: i32 = (-42 as i32).saturating_sub(2); -const INT_I32_NEG_SUB: i32 = i32::min_value().saturating_sub(1); -const INT_I32_POS_SUB: i32 = i32::max_value().saturating_sub(-1); -const INT_U128_SUB: u128 = (0 as u128).saturating_sub(1); -const INT_I128_NEG_SUB: i128 = i128::min_value().saturating_sub(1); -const INT_I128_POS_SUB: i128 = i128::max_value().saturating_sub(-1); +const ADD_INT_U32_NO: u32 = (42 as u32).saturating_add(2); +const ADD_INT_U32: u32 = u32::max_value().saturating_add(1); +const ADD_INT_U128: u128 = u128::max_value().saturating_add(1); +const ADD_INT_I128: i128 = i128::max_value().saturating_add(1); +const ADD_INT_I128_NEG: i128 = i128::min_value().saturating_add(-1); + +const SUB_INT_U32_NO: u32 = (42 as u32).saturating_sub(2); +const SUB_INT_U32: u32 = (1 as u32).saturating_sub(2); +const SUB_INT_I32_NO: i32 = (-42 as i32).saturating_sub(2); +const SUB_INT_I32_NEG: i32 = i32::min_value().saturating_sub(1); +const SUB_INT_I32_POS: i32 = i32::max_value().saturating_sub(-1); +const SUB_INT_U128: u128 = (0 as u128).saturating_sub(1); +const SUB_INT_I128_NEG: i128 = i128::min_value().saturating_sub(1); +const SUB_INT_I128_POS: i128 = i128::max_value().saturating_sub(-1); + +const MUL_INT_U32_NO: u32 = (42 as u32).saturating_mul(2); +const MUL_INT_U32: u32 = (1 as u32).saturating_mul(2); +const MUL_INT_I32_NO: i32 = (-42 as i32).saturating_mul(2); +const MUL_INT_I32_NEG: i32 = i32::min_value().saturating_mul(1); +const MUL_INT_I32_POS: i32 = i32::max_value().saturating_mul(2); +const MUL_INT_U128: u128 = (0 as u128).saturating_mul(1); +const MUL_INT_I128_NEG: i128 = i128::min_value().saturating_mul(2); +const MUL_INT_I128_POS: i128 = i128::max_value().saturating_mul(2); + +const NEG_INT_I8: i8 = (-42i8).saturating_neg(); +const NEG_INT_I8_B: i8 = i8::min_value().saturating_neg(); +const NEG_INT_I32: i32 = i32::min_value().saturating_neg(); +const NEG_INT_I32_B: i32 = i32::max_value().saturating_neg(); +const NEG_INT_I128: i128 = i128::min_value().saturating_neg(); +const NEG_INT_I128_B: i128 = i128::max_value().saturating_neg(); + +const ABS_INT_I8_A: i8 = 4i8.saturating_abs(); +const ABS_INT_I8_B: i8 = -4i8.saturating_abs(); +const ABS_INT_I8_C: i8 = i8::min_value().saturating_abs(); +const ABS_INT_I32_A: i32 = 4i32.saturating_abs(); +const ABS_INT_I32_B: i32 = -4i32.saturating_abs(); +const ABS_INT_I32_C: i32 = i32::min_value().saturating_abs(); +const ABS_INT_I128_A: i128 = 4i128.saturating_abs(); +const ABS_INT_I128_B: i128 = -4i128.saturating_abs(); +const ABS_INT_I128_C: i128 = i128::min_value().saturating_abs(); fn main() { - assert_eq!(INT_U32_NO, 44); - assert_eq!(INT_U32, u32::max_value()); - assert_eq!(INT_U128, u128::max_value()); - assert_eq!(INT_I128, i128::max_value()); - assert_eq!(INT_I128_NEG, i128::min_value()); - - assert_eq!(INT_U32_NO_SUB, 40); - assert_eq!(INT_U32_SUB, 0); - assert_eq!(INT_I32_NO_SUB, -44); - assert_eq!(INT_I32_NEG_SUB, i32::min_value()); - assert_eq!(INT_I32_POS_SUB, i32::max_value()); - assert_eq!(INT_U128_SUB, 0); - assert_eq!(INT_I128_NEG_SUB, i128::min_value()); - assert_eq!(INT_I128_POS_SUB, i128::max_value()); + assert_eq!(ADD_INT_U32_NO, 44); + assert_eq!(ADD_INT_U32, u32::max_value()); + assert_eq!(ADD_INT_U128, u128::max_value()); + assert_eq!(ADD_INT_I128, i128::max_value()); + assert_eq!(ADD_INT_I128_NEG, i128::min_value()); + + assert_eq!(SUB_INT_U32_NO, 40); + assert_eq!(SUB_INT_U32, 0); + assert_eq!(SUB_INT_I32_NO, -44); + assert_eq!(SUB_INT_I32_NEG, i32::min_value()); + assert_eq!(SUB_INT_I32_POS, i32::max_value()); + assert_eq!(SUB_INT_U128, 0); + assert_eq!(SUB_INT_I128_NEG, i128::min_value()); + assert_eq!(SUB_INT_I128_POS, i128::max_value()); + + assert_eq!(MUL_INT_U32_NO, 84); + assert_eq!(MUL_INT_U32, 2); + assert_eq!(MUL_INT_I32_NO, -84); + assert_eq!(MUL_INT_I32_NEG, i32::min_value()); + assert_eq!(MUL_INT_I32_POS, i32::max_value()); + assert_eq!(MUL_INT_U128, 0); + assert_eq!(MUL_INT_I128_NEG, i128::min_value()); + assert_eq!(MUL_INT_I128_POS, i128::max_value()); + + assert_eq!(NEG_INT_I8, 42); + assert_eq!(NEG_INT_I8_B, i8::max_value()); + assert_eq!(NEG_INT_I32, i32::max_value()); + assert_eq!(NEG_INT_I32_B, i32::min_value() + 1); + assert_eq!(NEG_INT_I128, i128::max_value()); + assert_eq!(NEG_INT_I128_B, i128::min_value() + 1); + + assert_eq!(ABS_INT_I8_A, 4i8); + assert_eq!(ABS_INT_I8_B, -4i8); + assert_eq!(ABS_INT_I8_C, i8::max_value()); + assert_eq!(ABS_INT_I32_A, 4i32); + assert_eq!(ABS_INT_I32_B, -4i32); + assert_eq!(ABS_INT_I32_C, i32::max_value()); + assert_eq!(ABS_INT_I128_A, 4i128); + assert_eq!(ABS_INT_I128_B, -4i128); + assert_eq!(ABS_INT_I128_C, i128::max_value()); } diff --git a/src/test/ui/consts/const-int-wrapping-rpass.rs b/src/test/ui/consts/const-int-wrapping-rpass.rs index 2bbad99a52a90..40b22464e596f 100644 --- a/src/test/ui/consts/const-int-wrapping-rpass.rs +++ b/src/test/ui/consts/const-int-wrapping-rpass.rs @@ -1,4 +1,5 @@ // run-pass +#![feature(const_int_wrapping)] const ADD_A: u32 = 200u32.wrapping_add(55); const ADD_B: u32 = 200u32.wrapping_add(u32::max_value()); @@ -22,6 +23,18 @@ const ABS_POS: i32 = 10i32.wrapping_abs(); const ABS_NEG: i32 = (-10i32).wrapping_abs(); const ABS_MIN: i32 = i32::min_value().wrapping_abs(); +const DIV_A: i8 = 8i8.wrapping_div(2); +const DIV_B: i8 = 8i8.wrapping_div(3); +const DIV_C: i8 = i8::min_value().wrapping_div(-1i8); +const DIV_D: u8 = 8u8.wrapping_div(2); +const DIV_E: u8 = 8u8.wrapping_div(3); + +const REM_A: i8 = 8i8.wrapping_rem(2); +const REM_B: i8 = 8i8.wrapping_rem(3); +const REM_C: i8 = i8::min_value().wrapping_rem(-1i8); +const REM_D: u8 = 8u8.wrapping_rem(2); +const REM_E: u8 = 8u8.wrapping_rem(3); + fn main() { assert_eq!(ADD_A, 255); assert_eq!(ADD_B, 199); @@ -44,4 +57,16 @@ fn main() { assert_eq!(ABS_POS, 10); assert_eq!(ABS_NEG, 10); assert_eq!(ABS_MIN, i32::min_value()); + + assert_eq!(DIV_A, 4i8); + assert_eq!(DIV_B, 2i8); + assert_eq!(DIV_C, i8::min_value()); + assert_eq!(DIV_D, 4u8); + assert_eq!(DIV_E, 2u8); + + assert_eq!(REM_A, 0i8); + assert_eq!(REM_B, 2i8); + assert_eq!(REM_C, 0i8); + assert_eq!(REM_D, 0u8); + assert_eq!(REM_E, 2u8); } diff --git a/src/test/ui/consts/const-nonzero.rs b/src/test/ui/consts/const-nonzero.rs deleted file mode 100644 index 6db3d1b3331fa..0000000000000 --- a/src/test/ui/consts/const-nonzero.rs +++ /dev/null @@ -1,9 +0,0 @@ -// build-pass (FIXME(62277): could be check-pass?) - -use std::num::NonZeroU8; - -const X: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(5) }; -const Y: u8 = X.get(); - -fn main() { -} diff --git a/src/test/ui/consts/const-option.rs b/src/test/ui/consts/const-option.rs new file mode 100644 index 0000000000000..eadca29984d0b --- /dev/null +++ b/src/test/ui/consts/const-option.rs @@ -0,0 +1,47 @@ +// run-pass +// aux-build:const_assert_lib.rs +use const_assert_lib::assert_same_const; + +#![feature(const_option_match)] +#![feature(option_result_contains)] + +assert_same_const! { + const SOME: Option = Some(3); + const NONE: Option = None; + + const IS_SOME_A: bool = SOME.is_some(); + const IS_SOME_B: bool = NONE.is_some(); + + const IS_NONE_A: bool = SOME.is_none(); + const IS_NONE_B: bool = NONE.is_none(); + + const AS_REF_A: Option<&i32> = SOME.as_ref(); + const AS_REF_B: Option<&i32> = NONE.as_ref(); + + const EXPECT_A: i32 = SOME.expect("This is dangerous!"); + + const UNWRAP_OR_A: i32 = SOME.unwrap_or(0); + const UNWRAP_OR_B: i32 = NONE.unwrap_or(0); + + const OK_OR_A: Result = SOME.ok_or(false); + const OK_OR_B: Result = NONE.ok_or(false); + + const AND_A: Option = SOME.and(Some(true)); + const AND_B: Option = SOME.and(None); + const AND_C: Option = NONE.and(Some(true)); + const AND_D: Option = NONE.and(None); + + const OR_A: Option = SOME.or(Some(1)); + const OR_B: Option = SOME.or(None); + const OR_C: Option = NONE.or(Some(1)); + const OR_D: Option = NONE.or(None); + + const XOR_A: Option = SOME.xor(Some(1)); + const XOR_B: Option = SOME.xor(None); + const XOR_C: Option = NONE.xor(Some(1)); + const XOR_D: Option = NONE.xor(None); + + const TRANSPOSE_A: Result, bool> = Some(Ok(2)).transpose(); + const TRANSPOSE_B: Result, bool> = Some(Err(false)).transpose(); + const TRANSPOSE_C: Result, bool> = None.transpose(); +}