Skip to content

Commit 5d2acad

Browse files
committed
constify Option methods
1 parent 7f2065a commit 5d2acad

File tree

1 file changed

+96
-40
lines changed

1 file changed

+96
-40
lines changed

library/core/src/option.rs

Lines changed: 96 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@
577577
#![stable(feature = "rust1", since = "1.0.0")]
578578

579579
use crate::iter::{self, FusedIterator, TrustedLen};
580+
use crate::marker::Destruct;
580581
use crate::ops::{self, ControlFlow, Deref, DerefMut};
581582
use crate::panicking::{panic, panic_display};
582583
use crate::pin::Pin;
@@ -649,7 +650,8 @@ impl<T> Option<T> {
649650
#[must_use]
650651
#[inline]
651652
#[stable(feature = "is_some_and", since = "1.70.0")]
652-
pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool {
653+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
654+
pub const fn is_some_and(self, f: impl ~const Destruct + ~const FnOnce(T) -> bool) -> bool {
653655
match self {
654656
None => false,
655657
Some(x) => f(x),
@@ -697,7 +699,8 @@ impl<T> Option<T> {
697699
#[must_use]
698700
#[inline]
699701
#[stable(feature = "is_none_or", since = "1.82.0")]
700-
pub fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool {
702+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
703+
pub const fn is_none_or(self, f: impl ~const Destruct + ~const FnOnce(T) -> bool) -> bool {
701704
match self {
702705
None => true,
703706
Some(x) => f(x),
@@ -1023,7 +1026,12 @@ impl<T> Option<T> {
10231026
/// ```
10241027
#[inline]
10251028
#[stable(feature = "rust1", since = "1.0.0")]
1026-
pub fn unwrap_or(self, default: T) -> T {
1029+
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
1030+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1031+
pub const fn unwrap_or(self, default: T) -> T
1032+
where
1033+
T: ~const Destruct,
1034+
{
10271035
match self {
10281036
Some(x) => x,
10291037
None => default,
@@ -1042,9 +1050,10 @@ impl<T> Option<T> {
10421050
#[inline]
10431051
#[track_caller]
10441052
#[stable(feature = "rust1", since = "1.0.0")]
1045-
pub fn unwrap_or_else<F>(self, f: F) -> T
1053+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1054+
pub const fn unwrap_or_else<F>(self, f: F) -> T
10461055
where
1047-
F: FnOnce() -> T,
1056+
F: ~const Destruct + ~const FnOnce() -> T,
10481057
{
10491058
match self {
10501059
Some(x) => x,
@@ -1073,9 +1082,10 @@ impl<T> Option<T> {
10731082
/// [`FromStr`]: crate::str::FromStr
10741083
#[inline]
10751084
#[stable(feature = "rust1", since = "1.0.0")]
1076-
pub fn unwrap_or_default(self) -> T
1085+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1086+
pub const fn unwrap_or_default(self) -> T
10771087
where
1078-
T: Default,
1088+
T: ~const Default,
10791089
{
10801090
match self {
10811091
Some(x) => x,
@@ -1139,9 +1149,10 @@ impl<T> Option<T> {
11391149
/// ```
11401150
#[inline]
11411151
#[stable(feature = "rust1", since = "1.0.0")]
1142-
pub fn map<U, F>(self, f: F) -> Option<U>
1152+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1153+
pub const fn map<U, F>(self, f: F) -> Option<U>
11431154
where
1144-
F: FnOnce(T) -> U,
1155+
F: ~const Destruct + ~const FnOnce(T) -> U,
11451156
{
11461157
match self {
11471158
Some(x) => Some(f(x)),
@@ -1169,7 +1180,11 @@ impl<T> Option<T> {
11691180
/// ```
11701181
#[inline]
11711182
#[stable(feature = "result_option_inspect", since = "1.76.0")]
1172-
pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
1183+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1184+
pub const fn inspect<F>(self, f: F) -> Self
1185+
where
1186+
F: ~const Destruct + ~const FnOnce(&T),
1187+
{
11731188
if let Some(ref x) = self {
11741189
f(x);
11751190
}
@@ -1198,9 +1213,10 @@ impl<T> Option<T> {
11981213
#[inline]
11991214
#[stable(feature = "rust1", since = "1.0.0")]
12001215
#[must_use = "if you don't need the returned value, use `if let` instead"]
1201-
pub fn map_or<U, F>(self, default: U, f: F) -> U
1216+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1217+
pub const fn map_or<U: ~const Destruct, F>(self, default: U, f: F) -> U
12021218
where
1203-
F: FnOnce(T) -> U,
1219+
F: ~const Destruct + ~const FnOnce(T) -> U,
12041220
{
12051221
match self {
12061222
Some(t) => f(t),
@@ -1243,10 +1259,11 @@ impl<T> Option<T> {
12431259
/// ```
12441260
#[inline]
12451261
#[stable(feature = "rust1", since = "1.0.0")]
1246-
pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
1262+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1263+
pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U
12471264
where
1248-
D: FnOnce() -> U,
1249-
F: FnOnce(T) -> U,
1265+
D: ~const Destruct + ~const FnOnce() -> U,
1266+
F: ~const Destruct + ~const FnOnce(T) -> U,
12501267
{
12511268
match self {
12521269
Some(t) => f(t),
@@ -1273,10 +1290,11 @@ impl<T> Option<T> {
12731290
/// [default value]: Default::default
12741291
#[inline]
12751292
#[unstable(feature = "result_option_map_or_default", issue = "138099")]
1276-
pub fn map_or_default<U, F>(self, f: F) -> U
1293+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1294+
pub const fn map_or_default<U, F>(self, f: F) -> U
12771295
where
1278-
U: Default,
1279-
F: FnOnce(T) -> U,
1296+
U: ~const Default,
1297+
F: ~const Destruct + ~const FnOnce(T) -> U,
12801298
{
12811299
match self {
12821300
Some(t) => f(t),
@@ -1307,7 +1325,8 @@ impl<T> Option<T> {
13071325
/// ```
13081326
#[inline]
13091327
#[stable(feature = "rust1", since = "1.0.0")]
1310-
pub fn ok_or<E>(self, err: E) -> Result<T, E> {
1328+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1329+
pub const fn ok_or<E: ~const Destruct>(self, err: E) -> Result<T, E> {
13111330
match self {
13121331
Some(v) => Ok(v),
13131332
None => Err(err),
@@ -1332,9 +1351,10 @@ impl<T> Option<T> {
13321351
/// ```
13331352
#[inline]
13341353
#[stable(feature = "rust1", since = "1.0.0")]
1335-
pub fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
1354+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1355+
pub const fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
13361356
where
1337-
F: FnOnce() -> E,
1357+
F: ~const Destruct + ~const FnOnce() -> E,
13381358
{
13391359
match self {
13401360
Some(v) => Ok(v),
@@ -1463,7 +1483,12 @@ impl<T> Option<T> {
14631483
/// ```
14641484
#[inline]
14651485
#[stable(feature = "rust1", since = "1.0.0")]
1466-
pub fn and<U>(self, optb: Option<U>) -> Option<U> {
1486+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1487+
pub const fn and<U>(self, optb: Option<U>) -> Option<U>
1488+
where
1489+
T: ~const Destruct,
1490+
U: ~const Destruct,
1491+
{
14671492
match self {
14681493
Some(_) => optb,
14691494
None => None,
@@ -1502,9 +1527,10 @@ impl<T> Option<T> {
15021527
#[inline]
15031528
#[stable(feature = "rust1", since = "1.0.0")]
15041529
#[rustc_confusables("flat_map", "flatmap")]
1505-
pub fn and_then<U, F>(self, f: F) -> Option<U>
1530+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1531+
pub const fn and_then<U, F>(self, f: F) -> Option<U>
15061532
where
1507-
F: FnOnce(T) -> Option<U>,
1533+
F: ~const Destruct + ~const FnOnce(T) -> Option<U>,
15081534
{
15091535
match self {
15101536
Some(x) => f(x),
@@ -1538,9 +1564,11 @@ impl<T> Option<T> {
15381564
/// [`Some(t)`]: Some
15391565
#[inline]
15401566
#[stable(feature = "option_filter", since = "1.27.0")]
1541-
pub fn filter<P>(self, predicate: P) -> Self
1567+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1568+
pub const fn filter<P>(self, predicate: P) -> Self
15421569
where
1543-
P: FnOnce(&T) -> bool,
1570+
P: ~const Destruct + ~const FnOnce(&T) -> bool,
1571+
T: ~const Destruct,
15441572
{
15451573
if let Some(x) = self {
15461574
if predicate(&x) {
@@ -1579,7 +1607,11 @@ impl<T> Option<T> {
15791607
/// ```
15801608
#[inline]
15811609
#[stable(feature = "rust1", since = "1.0.0")]
1582-
pub fn or(self, optb: Option<T>) -> Option<T> {
1610+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1611+
pub const fn or(self, optb: Option<T>) -> Option<T>
1612+
where
1613+
T: ~const Destruct,
1614+
{
15831615
match self {
15841616
x @ Some(_) => x,
15851617
None => optb,
@@ -1601,9 +1633,13 @@ impl<T> Option<T> {
16011633
/// ```
16021634
#[inline]
16031635
#[stable(feature = "rust1", since = "1.0.0")]
1604-
pub fn or_else<F>(self, f: F) -> Option<T>
1636+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1637+
pub const fn or_else<F>(self, f: F) -> Option<T>
16051638
where
1606-
F: FnOnce() -> Option<T>,
1639+
F: ~const Destruct + ~const FnOnce() -> Option<T>,
1640+
//FIXME(const_hack): this `T: ~const Destruct` is unnecessary, but even precise live drops can't tell
1641+
// no value of type `T` gets dropped here
1642+
T: ~const Destruct,
16071643
{
16081644
match self {
16091645
x @ Some(_) => x,
@@ -1634,7 +1670,11 @@ impl<T> Option<T> {
16341670
/// ```
16351671
#[inline]
16361672
#[stable(feature = "option_xor", since = "1.37.0")]
1637-
pub fn xor(self, optb: Option<T>) -> Option<T> {
1673+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1674+
pub const fn xor(self, optb: Option<T>) -> Option<T>
1675+
where
1676+
T: ~const Destruct,
1677+
{
16381678
match (self, optb) {
16391679
(a @ Some(_), None) => a,
16401680
(None, b @ Some(_)) => b,
@@ -1668,7 +1708,11 @@ impl<T> Option<T> {
16681708
#[must_use = "if you intended to set a value, consider assignment instead"]
16691709
#[inline]
16701710
#[stable(feature = "option_insert", since = "1.53.0")]
1671-
pub fn insert(&mut self, value: T) -> &mut T {
1711+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1712+
pub const fn insert(&mut self, value: T) -> &mut T
1713+
where
1714+
T: ~const Destruct,
1715+
{
16721716
*self = Some(value);
16731717

16741718
// SAFETY: the code above just filled the option
@@ -1720,9 +1764,10 @@ impl<T> Option<T> {
17201764
/// ```
17211765
#[inline]
17221766
#[stable(feature = "option_get_or_insert_default", since = "1.83.0")]
1723-
pub fn get_or_insert_default(&mut self) -> &mut T
1767+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1768+
pub const fn get_or_insert_default(&mut self) -> &mut T
17241769
where
1725-
T: Default,
1770+
T: ~const Default + ~const Destruct,
17261771
{
17271772
self.get_or_insert_with(T::default)
17281773
}
@@ -1746,9 +1791,11 @@ impl<T> Option<T> {
17461791
/// ```
17471792
#[inline]
17481793
#[stable(feature = "option_entry", since = "1.20.0")]
1749-
pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
1794+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1795+
pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
17501796
where
1751-
F: FnOnce() -> T,
1797+
F: ~const Destruct + ~const FnOnce() -> T,
1798+
T: ~const Destruct,
17521799
{
17531800
if let None = self {
17541801
*self = Some(f());
@@ -1812,9 +1859,10 @@ impl<T> Option<T> {
18121859
/// ```
18131860
#[inline]
18141861
#[stable(feature = "option_take_if", since = "1.80.0")]
1815-
pub fn take_if<P>(&mut self, predicate: P) -> Option<T>
1862+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1863+
pub const fn take_if<P>(&mut self, predicate: P) -> Option<T>
18161864
where
1817-
P: FnOnce(&mut T) -> bool,
1865+
P: ~const Destruct + ~const FnOnce(&mut T) -> bool,
18181866
{
18191867
if self.as_mut().map_or(false, predicate) { self.take() } else { None }
18201868
}
@@ -1859,7 +1907,12 @@ impl<T> Option<T> {
18591907
/// assert_eq!(x.zip(z), None);
18601908
/// ```
18611909
#[stable(feature = "option_zip_option", since = "1.46.0")]
1862-
pub fn zip<U>(self, other: Option<U>) -> Option<(T, U)> {
1910+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1911+
pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)>
1912+
where
1913+
T: ~const Destruct,
1914+
U: ~const Destruct,
1915+
{
18631916
match (self, other) {
18641917
(Some(a), Some(b)) => Some((a, b)),
18651918
_ => None,
@@ -1895,9 +1948,12 @@ impl<T> Option<T> {
18951948
/// assert_eq!(x.zip_with(None, Point::new), None);
18961949
/// ```
18971950
#[unstable(feature = "option_zip", issue = "70086")]
1898-
pub fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
1951+
#[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
1952+
pub const fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
18991953
where
1900-
F: FnOnce(T, U) -> R,
1954+
F: ~const Destruct + ~const FnOnce(T, U) -> R,
1955+
T: ~const Destruct,
1956+
U: ~const Destruct,
19011957
{
19021958
match (self, other) {
19031959
(Some(a), Some(b)) => Some(f(a, b)),

0 commit comments

Comments
 (0)