Rollup merge of #147788 - clarfonthey:const-cell, r=oli-obk

const Cell methods

Tracking: rust-lang/rust#147787

r? `@oli-obk`
This commit is contained in:
Matthias Krüger
2025-10-22 07:12:11 +02:00
committed by GitHub
4 changed files with 57 additions and 44 deletions
+17 -4
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 @@ pub const fn new(value: 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 @@ pub const fn get(&self) -> 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())
}
}
+1
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)]
+38
View File
@@ -27,3 +27,41 @@ fn drop(&mut self) {
drop(x);
drop(y);
}
#[test]
fn const_drop_in_place() {
const COUNTER: usize = {
use core::cell::Cell;
let counter = Cell::new(0);
// only exists to make `Drop` indirect impl
#[allow(dead_code)]
struct Test<'a>(Dropped<'a>);
struct Dropped<'a>(&'a Cell<usize>);
impl const Drop for Dropped<'_> {
fn drop(&mut self) {
self.0.set(self.0.get() + 1);
}
}
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.get() == 1);
unsafe {
ManuallyDrop::drop(&mut two);
}
assert!(counter.get() == 2);
unsafe {
ManuallyDrop::drop(&mut three);
}
counter.get()
};
assert_eq!(COUNTER, 3);
}
+1 -40
View File
@@ -1,6 +1,6 @@
use core::cell::RefCell;
use core::marker::Freeze;
use core::mem::{ManuallyDrop, MaybeUninit};
use core::mem::MaybeUninit;
use core::num::NonZero;
use core::ptr;
use core::ptr::*;
@@ -1045,42 +1045,3 @@ struct PtrMutDefaultTest {
let default = PtrMutDefaultTest::default();
assert!(default.ptr.is_null());
}
#[test]
fn test_const_drop_in_place() {
const COUNTER: usize = {
let mut counter = 0;
let counter_ptr = &raw mut counter;
// only exists to make `Drop` indirect impl
#[allow(dead_code)]
struct Test(Dropped);
struct Dropped(*mut usize);
impl const Drop for Dropped {
fn drop(&mut self) {
unsafe {
*self.0 += 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);
unsafe {
ManuallyDrop::drop(&mut one);
}
assert!(counter == 1);
unsafe {
ManuallyDrop::drop(&mut two);
}
assert!(counter == 2);
unsafe {
ManuallyDrop::drop(&mut three);
}
counter
};
assert_eq!(COUNTER, 3);
}