Skip to content

Commit

Permalink
const fn for option copied, take & replace + tests
Browse files Browse the repository at this point in the history
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
  • Loading branch information
lambinoo committed Aug 29, 2021
1 parent 757a65b commit 10ddabc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Expand Up @@ -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)]
Expand Down
23 changes: 16 additions & 7 deletions library/core/src/option.rs
Expand Up @@ -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(_))
}
Expand All @@ -560,8 +560,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()
}
Expand Down Expand Up @@ -1312,8 +1312,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,
Expand All @@ -1334,8 +1336,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))
}

Expand Down Expand Up @@ -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,
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions library/core/tests/option.rs
Expand Up @@ -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]
Expand Down

0 comments on commit 10ddabc

Please sign in to comment.