const Cell methods

This commit is contained in:
ltdk 2025-10-16 15:04:43 -04:00
parent 779e19d8ba
commit 97b7170eef
3 changed files with 32 additions and 19 deletions

View file

@ -252,7 +252,7 @@
use crate::cmp::Ordering;
use crate::fmt::{self, Debug, Display};
use crate::marker::{PhantomData, Unsize};
use crate::marker::{Destruct, PhantomData, Unsize};
use crate::mem::{self, ManuallyDrop};
use crate::ops::{self, CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
use crate::panic::const_panic;
@ -429,7 +429,11 @@ impl<T> Cell<T> {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set(&self, val: T) {
#[rustc_const_unstable(feature = "const_cell_traits", issue = "147787")]
pub const fn set(&self, val: T)
where
T: [const] Destruct,
{
self.replace(val);
}
@ -561,7 +565,12 @@ impl<T: Copy> Cell<T> {
/// ```
#[inline]
#[stable(feature = "cell_update", since = "1.88.0")]
pub fn update(&self, f: impl FnOnce(T) -> T) {
#[rustc_const_unstable(feature = "const_cell_traits", issue = "147787")]
pub const fn update(&self, f: impl [const] FnOnce(T) -> T)
where
// FIXME(const-hack): `Copy` should imply `const Destruct`
T: [const] Destruct,
{
let old = self.get();
self.set(f(old));
}
@ -654,7 +663,11 @@ impl<T: Default> Cell<T> {
/// assert_eq!(c.into_inner(), 0);
/// ```
#[stable(feature = "move_cell", since = "1.17.0")]
pub fn take(&self) -> T {
#[rustc_const_unstable(feature = "const_cell_traits", issue = "147787")]
pub const fn take(&self) -> T
where
T: [const] Default,
{
self.replace(Default::default())
}
}

View file

@ -16,6 +16,7 @@
#![feature(char_internals)]
#![feature(char_max_len)]
#![feature(clone_to_uninit)]
#![feature(const_cell_traits)]
#![feature(const_cmp)]
#![feature(const_convert)]
#![feature(const_destruct)]

View file

@ -1049,38 +1049,37 @@ fn test_ptr_default() {
#[test]
fn test_const_drop_in_place() {
const COUNTER: usize = {
let mut counter = 0;
let counter_ptr = &raw mut counter;
use core::cell::Cell;
let counter = Cell::new(0);
// only exists to make `Drop` indirect impl
#[allow(dead_code)]
struct Test(Dropped);
struct Test<'a>(Dropped<'a>);
struct Dropped(*mut usize);
impl const Drop for Dropped {
struct Dropped<'a>(&'a Cell<usize>);
impl const Drop for Dropped<'_> {
fn drop(&mut self) {
unsafe {
*self.0 += 1;
}
self.0.set(self.0.get() + 1);
}
}
let mut one = ManuallyDrop::new(Test(Dropped(counter_ptr)));
let mut two = ManuallyDrop::new(Test(Dropped(counter_ptr)));
let mut three = ManuallyDrop::new(Test(Dropped(counter_ptr)));
assert!(counter == 0);
let mut one = ManuallyDrop::new(Test(Dropped(&counter)));
let mut two = ManuallyDrop::new(Test(Dropped(&counter)));
let mut three = ManuallyDrop::new(Test(Dropped(&counter)));
assert!(counter.get() == 0);
unsafe {
ManuallyDrop::drop(&mut one);
}
assert!(counter == 1);
assert!(counter.get() == 1);
unsafe {
ManuallyDrop::drop(&mut two);
}
assert!(counter == 2);
assert!(counter.get() == 2);
unsafe {
ManuallyDrop::drop(&mut three);
}
counter
counter.get()
};
assert_eq!(COUNTER, 3);
}