Skip to content

Commit 1c4129d

Browse files
authored
Rollup merge of rust-lang#86828 - lambinoo:67441-const-fn-copied-take-replace, r=joshtriplett
const fn for option copied, take & replace Tracking issue: [rust-lang#67441](rust-lang#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!
2 parents 484032f + 10ddabc commit 1c4129d

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#![feature(const_maybe_uninit_assume_init)]
9292
#![feature(const_option)]
9393
#![feature(const_pin)]
94+
#![feature(const_replace)]
9495
#![feature(const_ptr_offset)]
9596
#![feature(const_ptr_offset_from)]
9697
#![feature(const_ptr_read)]

library/core/src/option.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,8 @@ impl<T> Option<T> {
544544
/// ```
545545
#[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
546546
#[inline]
547-
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
548547
#[stable(feature = "rust1", since = "1.0.0")]
548+
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
549549
pub const fn is_some(&self) -> bool {
550550
matches!(*self, Some(_))
551551
}
@@ -564,8 +564,8 @@ impl<T> Option<T> {
564564
#[must_use = "if you intended to assert that this doesn't have a value, consider \
565565
`.and_then(|_| panic!(\"`Option` had a value when expected `None`\"))` instead"]
566566
#[inline]
567-
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
568567
#[stable(feature = "rust1", since = "1.0.0")]
568+
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
569569
pub const fn is_none(&self) -> bool {
570570
!self.is_some()
571571
}
@@ -1318,8 +1318,10 @@ impl<T> Option<T> {
13181318
/// ```
13191319
#[inline]
13201320
#[stable(feature = "rust1", since = "1.0.0")]
1321-
pub fn take(&mut self) -> Option<T> {
1322-
mem::take(self)
1321+
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
1322+
pub const fn take(&mut self) -> Option<T> {
1323+
// FIXME replace `mem::replace` by `mem::take` when the latter is const ready
1324+
mem::replace(self, None)
13231325
}
13241326

13251327
/// Replaces the actual value in the option by the value given in parameter,
@@ -1340,8 +1342,9 @@ impl<T> Option<T> {
13401342
/// assert_eq!(old, None);
13411343
/// ```
13421344
#[inline]
1345+
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
13431346
#[stable(feature = "option_replace", since = "1.31.0")]
1344-
pub fn replace(&mut self, value: T) -> Option<T> {
1347+
pub const fn replace(&mut self, value: T) -> Option<T> {
13451348
mem::replace(self, Some(value))
13461349
}
13471350

@@ -1446,8 +1449,14 @@ impl<T: Copy> Option<&T> {
14461449
/// assert_eq!(copied, Some(12));
14471450
/// ```
14481451
#[stable(feature = "copied", since = "1.35.0")]
1449-
pub fn copied(self) -> Option<T> {
1450-
self.map(|&t| t)
1452+
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
1453+
pub const fn copied(self) -> Option<T> {
1454+
// FIXME: this implementation, which sidesteps using `Option::map` since it's not const
1455+
// ready yet, should be reverted when possible to avoid code repetition
1456+
match self {
1457+
Some(&v) => Some(v),
1458+
None => None,
1459+
}
14511460
}
14521461
}
14531462

library/core/tests/option.rs

+13
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,19 @@ fn option_const() {
367367

368368
const IS_NONE: bool = OPTION.is_none();
369369
assert!(!IS_NONE);
370+
371+
const COPIED: Option<usize> = OPTION.as_ref().copied();
372+
assert_eq!(COPIED, OPTION);
373+
}
374+
375+
#[test]
376+
const fn option_const_mut() {
377+
// test that the methods of `Option` that take mutable references are usable in a const context
378+
379+
let mut option: Option<usize> = Some(32);
380+
381+
let _take = option.take();
382+
let _replace = option.replace(42);
370383
}
371384

372385
#[test]

0 commit comments

Comments
 (0)