From 10ddabc194cc3349d4cd0951b00484d736edc6aa Mon Sep 17 00:00:00 2001 From: Lamb Date: Fri, 2 Jul 2021 23:34:52 +0200 Subject: [PATCH] const fn for option copied, take & replace + tests 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 | 1 + library/core/src/option.rs | 23 ++++++++++++++++------- library/core/tests/option.rs | 13 +++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1a6d1aed2fd1e..28433f734c656 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 47865240f6a6f..59ebc90222402 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -540,8 +540,8 @@ impl Option { /// ``` #[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 @@ impl Option { #[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 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn take(&mut self) -> Option { - mem::take(self) + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn take(&mut self) -> Option { + // 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 @@ impl Option { /// 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 { + pub const fn replace(&mut self, value: T) -> Option { mem::replace(self, Some(value)) } @@ -1440,8 +1443,14 @@ impl Option<&T> { /// assert_eq!(copied, Some(12)); /// ``` #[stable(feature = "copied", since = "1.35.0")] - pub fn copied(self) -> Option { - self.map(|&t| t) + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn copied(self) -> Option { + // 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 cd8fdebe36a05..8995f96b1238a 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 = 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 = Some(32); + + let _take = option.take(); + let _replace = option.replace(42); } #[test]