]> git.lizzy.rs Git - rust.git/commitdiff
const fn for option copied, take & replace + tests
authorLamb <contact@lambtowolf.me>
Fri, 2 Jul 2021 21:34:52 +0000 (23:34 +0200)
committerLamb <contact@ltow.me>
Sun, 29 Aug 2021 11:19:17 +0000 (13:19 +0200)
fix: move test that require mut to another

Adding TODOs for Option::take and Option::copied

TODO to FIXME + moving const stability under normal

Moving const stability attr under normal stab attr

move more rustc stability attributes

library/core/src/lib.rs
library/core/src/option.rs
library/core/tests/option.rs

index 1a6d1aed2fd1edea75668e17f86fabb92962b917..28433f734c656e6be7b4b06fc8c50ece4847acd2 100644 (file)
@@ -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)]
index 47865240f6a6fdaf601cc57ed7082acf9c37c50e..59ebc902224029dfc59695ee843227489a093d4a 100644 (file)
@@ -540,8 +540,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(_))
     }
@@ -560,8 +560,8 @@ pub const fn is_some(&self) -> bool {
     #[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()
     }
@@ -1312,8 +1312,10 @@ pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut 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,
@@ -1334,8 +1336,9 @@ pub fn take(&mut self) -> 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))
     }
 
@@ -1440,8 +1443,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,
+        }
     }
 }
 
index cd8fdebe36a05a1620ee90daf9417f1e45575afd..8995f96b1238a654badb66cece7ed962f109dd3c 100644 (file)
@@ -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]