about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2021-10-03 23:13:16 -0700
committerGitHub <noreply@github.com>2021-10-03 23:13:16 -0700
commit287af0403a0cf0f9594b4eb2159235751487fba9 (patch)
tree8a136f507099cc27a520c5f5697cc3a5c41911bf
parent22714ed4e3954b3d60b3650bad743ec4b3d64d27 (diff)
parent10ddabc194cc3349d4cd0951b00484d736edc6aa (diff)
Rollup merge of #86828 - lambinoo:67441-const-fn-copied-take-replace, r=joshtriplett
const fn for option copied, take & replace

Tracking issue: [#67441](https://github.com/rust-lang/rust/issues/67441)

Adding const fn for the copied, take and replace method of Option. Also adding necessary unit test.

It's my first contribution so I am pretty sure I don't know what I'm doing but there's a first for everything!
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/option.rs23
-rw-r--r--library/core/tests/option.rs13
3 files changed, 30 insertions, 7 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 2230461b5f4..45ef1fcde2a 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -91,6 +91,7 @@
 #![feature(const_maybe_uninit_assume_init)]
 #![feature(const_option)]
 #![feature(const_pin)]
+#![feature(const_replace)]
 #![feature(const_ptr_offset)]
 #![feature(const_ptr_offset_from)]
 #![feature(const_ptr_read)]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index b2cc7145702..3259e142a0c 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -544,8 +544,8 @@ impl<T> Option<T> {
     /// ```
     #[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
     #[inline]
-    #[rustc_const_stable(feature = "const_option", since = "1.48.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "const_option", since = "1.48.0")]
     pub const fn is_some(&self) -> bool {
         matches!(*self, Some(_))
     }
@@ -564,8 +564,8 @@ impl<T> Option<T> {
     #[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]
-    #[rustc_const_stable(feature = "const_option", since = "1.48.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "const_option", since = "1.48.0")]
     pub const fn is_none(&self) -> bool {
         !self.is_some()
     }
@@ -1318,8 +1318,10 @@ impl<T> Option<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn take(&mut self) -> Option<T> {
-        mem::take(self)
+    #[rustc_const_unstable(feature = "const_option", issue = "67441")]
+    pub const fn take(&mut self) -> Option<T> {
+        // FIXME replace `mem::replace` by `mem::take` when the latter is const ready
+        mem::replace(self, None)
     }
 
     /// Replaces the actual value in the option by the value given in parameter,
@@ -1340,8 +1342,9 @@ impl<T> Option<T> {
     /// assert_eq!(old, None);
     /// ```
     #[inline]
+    #[rustc_const_unstable(feature = "const_option", issue = "67441")]
     #[stable(feature = "option_replace", since = "1.31.0")]
-    pub fn replace(&mut self, value: T) -> Option<T> {
+    pub const fn replace(&mut self, value: T) -> Option<T> {
         mem::replace(self, Some(value))
     }
 
@@ -1446,8 +1449,14 @@ impl<T: Copy> Option<&T> {
     /// assert_eq!(copied, Some(12));
     /// ```
     #[stable(feature = "copied", since = "1.35.0")]
-    pub fn copied(self) -> Option<T> {
-        self.map(|&t| t)
+    #[rustc_const_unstable(feature = "const_option", issue = "67441")]
+    pub const fn copied(self) -> Option<T> {
+        // FIXME: this implementation, which sidesteps using `Option::map` since it's not const
+        // ready yet, should be reverted when possible to avoid code repetition
+        match self {
+            Some(&v) => Some(v),
+            None => None,
+        }
     }
 }
 
diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs
index cd8fdebe36a..8995f96b123 100644
--- a/library/core/tests/option.rs
+++ b/library/core/tests/option.rs
@@ -367,6 +367,19 @@ fn option_const() {
 
     const IS_NONE: bool = OPTION.is_none();
     assert!(!IS_NONE);
+
+    const COPIED: Option<usize> = OPTION.as_ref().copied();
+    assert_eq!(COPIED, OPTION);
+}
+
+#[test]
+const fn option_const_mut() {
+    // test that the methods of `Option` that take mutable references are usable in a const context
+
+    let mut option: Option<usize> = Some(32);
+
+    let _take = option.take();
+    let _replace = option.replace(42);
 }
 
 #[test]