about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <github333195615777966@oli-obk.de>2025-07-15 09:57:44 +0000
committerOli Scherer <github333195615777966@oli-obk.de>2025-07-17 09:11:05 +0000
commit853333d4bdc7570b74e4bf02d506c2951a9d3e4b (patch)
tree66facce967f3dcd385b94d8e154ac88041e80c3d
parent014bd8290f084c714995205a9116e6c035419ae6 (diff)
downloadrust-853333d4bdc7570b74e4bf02d506c2951a9d3e4b.tar.gz
rust-853333d4bdc7570b74e4bf02d506c2951a9d3e4b.zip
constify `Option` methods
-rw-r--r--library/core/src/option.rs137
1 files changed, 97 insertions, 40 deletions
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 9f432758a66..7633429fc5c 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -577,6 +577,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::iter::{self, FusedIterator, TrustedLen};
+use crate::marker::Destruct;
 use crate::ops::{self, ControlFlow, Deref, DerefMut};
 use crate::panicking::{panic, panic_display};
 use crate::pin::Pin;
@@ -649,7 +650,8 @@ impl<T> Option<T> {
     #[must_use]
     #[inline]
     #[stable(feature = "is_some_and", since = "1.70.0")]
-    pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn is_some_and(self, f: impl ~const FnOnce(T) -> bool + ~const Destruct) -> bool {
         match self {
             None => false,
             Some(x) => f(x),
@@ -697,7 +699,8 @@ impl<T> Option<T> {
     #[must_use]
     #[inline]
     #[stable(feature = "is_none_or", since = "1.82.0")]
-    pub fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn is_none_or(self, f: impl ~const FnOnce(T) -> bool + ~const Destruct) -> bool {
         match self {
             None => true,
             Some(x) => f(x),
@@ -1023,7 +1026,12 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unwrap_or(self, default: T) -> T {
+    #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn unwrap_or(self, default: T) -> T
+    where
+        T: ~const Destruct,
+    {
         match self {
             Some(x) => x,
             None => default,
@@ -1042,9 +1050,10 @@ impl<T> Option<T> {
     #[inline]
     #[track_caller]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unwrap_or_else<F>(self, f: F) -> T
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn unwrap_or_else<F>(self, f: F) -> T
     where
-        F: FnOnce() -> T,
+        F: ~const FnOnce() -> T + ~const Destruct,
     {
         match self {
             Some(x) => x,
@@ -1073,9 +1082,10 @@ impl<T> Option<T> {
     /// [`FromStr`]: crate::str::FromStr
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn unwrap_or_default(self) -> T
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn unwrap_or_default(self) -> T
     where
-        T: Default,
+        T: ~const Default,
     {
         match self {
             Some(x) => x,
@@ -1139,9 +1149,10 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn map<U, F>(self, f: F) -> Option<U>
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn map<U, F>(self, f: F) -> Option<U>
     where
-        F: FnOnce(T) -> U,
+        F: ~const FnOnce(T) -> U + ~const Destruct,
     {
         match self {
             Some(x) => Some(f(x)),
@@ -1169,7 +1180,11 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "result_option_inspect", since = "1.76.0")]
-    pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn inspect<F>(self, f: F) -> Self
+    where
+        F: ~const FnOnce(&T) + ~const Destruct,
+    {
         if let Some(ref x) = self {
             f(x);
         }
@@ -1198,9 +1213,11 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use = "if you don't need the returned value, use `if let` instead"]
-    pub fn map_or<U, F>(self, default: U, f: F) -> U
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn map_or<U, F>(self, default: U, f: F) -> U
     where
-        F: FnOnce(T) -> U,
+        F: ~const FnOnce(T) -> U + ~const Destruct,
+        U: ~const Destruct,
     {
         match self {
             Some(t) => f(t),
@@ -1243,10 +1260,11 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U
     where
-        D: FnOnce() -> U,
-        F: FnOnce(T) -> U,
+        D: ~const FnOnce() -> U + ~const Destruct,
+        F: ~const FnOnce(T) -> U + ~const Destruct,
     {
         match self {
             Some(t) => f(t),
@@ -1273,10 +1291,11 @@ impl<T> Option<T> {
     /// [default value]: Default::default
     #[inline]
     #[unstable(feature = "result_option_map_or_default", issue = "138099")]
-    pub fn map_or_default<U, F>(self, f: F) -> U
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn map_or_default<U, F>(self, f: F) -> U
     where
-        U: Default,
-        F: FnOnce(T) -> U,
+        U: ~const Default,
+        F: ~const FnOnce(T) -> U + ~const Destruct,
     {
         match self {
             Some(t) => f(t),
@@ -1307,7 +1326,8 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn ok_or<E>(self, err: E) -> Result<T, E> {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn ok_or<E: ~const Destruct>(self, err: E) -> Result<T, E> {
         match self {
             Some(v) => Ok(v),
             None => Err(err),
@@ -1332,9 +1352,10 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
     where
-        F: FnOnce() -> E,
+        F: ~const FnOnce() -> E + ~const Destruct,
     {
         match self {
             Some(v) => Ok(v),
@@ -1463,7 +1484,12 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn and<U>(self, optb: Option<U>) -> Option<U> {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn and<U>(self, optb: Option<U>) -> Option<U>
+    where
+        T: ~const Destruct,
+        U: ~const Destruct,
+    {
         match self {
             Some(_) => optb,
             None => None,
@@ -1502,9 +1528,10 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_confusables("flat_map", "flatmap")]
-    pub fn and_then<U, F>(self, f: F) -> Option<U>
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn and_then<U, F>(self, f: F) -> Option<U>
     where
-        F: FnOnce(T) -> Option<U>,
+        F: ~const FnOnce(T) -> Option<U> + ~const Destruct,
     {
         match self {
             Some(x) => f(x),
@@ -1538,9 +1565,11 @@ impl<T> Option<T> {
     /// [`Some(t)`]: Some
     #[inline]
     #[stable(feature = "option_filter", since = "1.27.0")]
-    pub fn filter<P>(self, predicate: P) -> Self
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn filter<P>(self, predicate: P) -> Self
     where
-        P: FnOnce(&T) -> bool,
+        P: ~const FnOnce(&T) -> bool + ~const Destruct,
+        T: ~const Destruct,
     {
         if let Some(x) = self {
             if predicate(&x) {
@@ -1579,7 +1608,11 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn or(self, optb: Option<T>) -> Option<T> {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn or(self, optb: Option<T>) -> Option<T>
+    where
+        T: ~const Destruct,
+    {
         match self {
             x @ Some(_) => x,
             None => optb,
@@ -1601,9 +1634,13 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn or_else<F>(self, f: F) -> Option<T>
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn or_else<F>(self, f: F) -> Option<T>
     where
-        F: FnOnce() -> Option<T>,
+        F: ~const FnOnce() -> Option<T> + ~const Destruct,
+        //FIXME(const_hack): this `T: ~const Destruct` is unnecessary, but even precise live drops can't tell
+        // no value of type `T` gets dropped here
+        T: ~const Destruct,
     {
         match self {
             x @ Some(_) => x,
@@ -1634,7 +1671,11 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "option_xor", since = "1.37.0")]
-    pub fn xor(self, optb: Option<T>) -> Option<T> {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn xor(self, optb: Option<T>) -> Option<T>
+    where
+        T: ~const Destruct,
+    {
         match (self, optb) {
             (a @ Some(_), None) => a,
             (None, b @ Some(_)) => b,
@@ -1668,7 +1709,11 @@ impl<T> Option<T> {
     #[must_use = "if you intended to set a value, consider assignment instead"]
     #[inline]
     #[stable(feature = "option_insert", since = "1.53.0")]
-    pub fn insert(&mut self, value: T) -> &mut T {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn insert(&mut self, value: T) -> &mut T
+    where
+        T: ~const Destruct,
+    {
         *self = Some(value);
 
         // SAFETY: the code above just filled the option
@@ -1720,9 +1765,10 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "option_get_or_insert_default", since = "1.83.0")]
-    pub fn get_or_insert_default(&mut self) -> &mut T
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn get_or_insert_default(&mut self) -> &mut T
     where
-        T: Default,
+        T: ~const Default + ~const Destruct,
     {
         self.get_or_insert_with(T::default)
     }
@@ -1746,9 +1792,11 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "option_entry", since = "1.20.0")]
-    pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
     where
-        F: FnOnce() -> T,
+        F: ~const FnOnce() -> T + ~const Destruct,
+        T: ~const Destruct,
     {
         if let None = self {
             *self = Some(f());
@@ -1812,9 +1860,10 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "option_take_if", since = "1.80.0")]
-    pub fn take_if<P>(&mut self, predicate: P) -> Option<T>
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn take_if<P>(&mut self, predicate: P) -> Option<T>
     where
-        P: FnOnce(&mut T) -> bool,
+        P: ~const FnOnce(&mut T) -> bool + ~const Destruct,
     {
         if self.as_mut().map_or(false, predicate) { self.take() } else { None }
     }
@@ -1859,7 +1908,12 @@ impl<T> Option<T> {
     /// assert_eq!(x.zip(z), None);
     /// ```
     #[stable(feature = "option_zip_option", since = "1.46.0")]
-    pub fn zip<U>(self, other: Option<U>) -> Option<(T, U)> {
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)>
+    where
+        T: ~const Destruct,
+        U: ~const Destruct,
+    {
         match (self, other) {
             (Some(a), Some(b)) => Some((a, b)),
             _ => None,
@@ -1895,9 +1949,12 @@ impl<T> Option<T> {
     /// assert_eq!(x.zip_with(None, Point::new), None);
     /// ```
     #[unstable(feature = "option_zip", issue = "70086")]
-    pub fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
+    #[rustc_const_unstable(feature = "const_option_ops", issue = "143956")]
+    pub const fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
     where
-        F: FnOnce(T, U) -> R,
+        F: ~const FnOnce(T, U) -> R + ~const Destruct,
+        T: ~const Destruct,
+        U: ~const Destruct,
     {
         match (self, other) {
             (Some(a), Some(b)) => Some(f(a, b)),