Skip to content

Commit eb4fc64

Browse files
committed
Constify Box<T, A> methods
1 parent 69ac533 commit eb4fc64

File tree

5 files changed

+224
-32
lines changed

5 files changed

+224
-32
lines changed

Diff for: library/alloc/src/alloc.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -323,17 +323,21 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
323323

324324
#[cfg_attr(not(test), lang = "box_free")]
325325
#[inline]
326+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
326327
// This signature has to be the same as `Box`, otherwise an ICE will happen.
327328
// When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as
328329
// well.
329330
// For example if `Box` is changed to `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`,
330331
// this function has to be changed to `fn box_free<T: ?Sized, A: Allocator>(Unique<T>, A)` as well.
331-
pub(crate) unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) {
332+
pub(crate) const unsafe fn box_free<T: ?Sized, A: ~const Allocator + ~const Drop>(
333+
ptr: Unique<T>,
334+
alloc: A,
335+
) {
332336
unsafe {
333337
let size = size_of_val(ptr.as_ref());
334338
let align = min_align_of_val(ptr.as_ref());
335339
let layout = Layout::from_size_align_unchecked(size, align);
336-
alloc.deallocate(ptr.cast().into(), layout)
340+
alloc.deallocate(From::from(ptr.cast()), layout)
337341
}
338342
}
339343

@@ -361,13 +365,22 @@ extern "Rust" {
361365
/// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
362366
/// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
363367
#[stable(feature = "global_alloc", since = "1.28.0")]
368+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
364369
#[cfg(all(not(no_global_oom_handling), not(test)))]
365370
#[rustc_allocator_nounwind]
366371
#[cold]
367-
pub fn handle_alloc_error(layout: Layout) -> ! {
368-
unsafe {
369-
__rust_alloc_error_handler(layout.size(), layout.align());
372+
pub const fn handle_alloc_error(layout: Layout) -> ! {
373+
const fn ct_error(_: Layout) -> ! {
374+
panic!("allocation failed");
370375
}
376+
377+
fn rt_error(layout: Layout) -> ! {
378+
unsafe {
379+
__rust_alloc_error_handler(layout.size(), layout.align());
380+
}
381+
}
382+
383+
unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) }
371384
}
372385

373386
// For alloc test `std::alloc::handle_alloc_error` can be used directly.

Diff for: library/alloc/src/boxed.rs

+68-24
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,13 @@ impl<T, A: Allocator> Box<T, A> {
346346
/// ```
347347
#[cfg(not(no_global_oom_handling))]
348348
#[unstable(feature = "allocator_api", issue = "32838")]
349+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
349350
#[must_use]
350351
#[inline]
351-
pub fn new_in(x: T, alloc: A) -> Self {
352+
pub const fn new_in(x: T, alloc: A) -> Self
353+
where
354+
A: ~const Allocator + ~const Drop,
355+
{
352356
let mut boxed = Self::new_uninit_in(alloc);
353357
unsafe {
354358
boxed.as_mut_ptr().write(x);
@@ -372,8 +376,13 @@ impl<T, A: Allocator> Box<T, A> {
372376
/// # Ok::<(), std::alloc::AllocError>(())
373377
/// ```
374378
#[unstable(feature = "allocator_api", issue = "32838")]
379+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
375380
#[inline]
376-
pub fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError> {
381+
pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
382+
where
383+
T: ~const Drop,
384+
A: ~const Allocator + ~const Drop,
385+
{
377386
let mut boxed = Self::try_new_uninit_in(alloc)?;
378387
unsafe {
379388
boxed.as_mut_ptr().write(x);
@@ -402,10 +411,14 @@ impl<T, A: Allocator> Box<T, A> {
402411
/// assert_eq!(*five, 5)
403412
/// ```
404413
#[unstable(feature = "allocator_api", issue = "32838")]
414+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
405415
#[cfg(not(no_global_oom_handling))]
406416
#[must_use]
407417
// #[unstable(feature = "new_uninit", issue = "63291")]
408-
pub fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
418+
pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
419+
where
420+
A: ~const Allocator + ~const Drop,
421+
{
409422
let layout = Layout::new::<mem::MaybeUninit<T>>();
410423
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
411424
// That would make code size bigger.
@@ -439,7 +452,11 @@ impl<T, A: Allocator> Box<T, A> {
439452
/// ```
440453
#[unstable(feature = "allocator_api", issue = "32838")]
441454
// #[unstable(feature = "new_uninit", issue = "63291")]
442-
pub fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
455+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
456+
pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
457+
where
458+
A: ~const Allocator + ~const Drop,
459+
{
443460
let layout = Layout::new::<mem::MaybeUninit<T>>();
444461
let ptr = alloc.allocate(layout)?.cast();
445462
unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
@@ -466,10 +483,14 @@ impl<T, A: Allocator> Box<T, A> {
466483
///
467484
/// [zeroed]: mem::MaybeUninit::zeroed
468485
#[unstable(feature = "allocator_api", issue = "32838")]
486+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
469487
#[cfg(not(no_global_oom_handling))]
470488
// #[unstable(feature = "new_uninit", issue = "63291")]
471489
#[must_use]
472-
pub fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
490+
pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
491+
where
492+
A: ~const Allocator + ~const Drop,
493+
{
473494
let layout = Layout::new::<mem::MaybeUninit<T>>();
474495
// NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
475496
// That would make code size bigger.
@@ -503,7 +524,11 @@ impl<T, A: Allocator> Box<T, A> {
503524
/// [zeroed]: mem::MaybeUninit::zeroed
504525
#[unstable(feature = "allocator_api", issue = "32838")]
505526
// #[unstable(feature = "new_uninit", issue = "63291")]
506-
pub fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError> {
527+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
528+
pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
529+
where
530+
A: ~const Allocator + ~const Drop,
531+
{
507532
let layout = Layout::new::<mem::MaybeUninit<T>>();
508533
let ptr = alloc.allocate_zeroed(layout)?.cast();
509534
unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
@@ -513,20 +538,22 @@ impl<T, A: Allocator> Box<T, A> {
513538
/// `x` will be pinned in memory and unable to be moved.
514539
#[cfg(not(no_global_oom_handling))]
515540
#[unstable(feature = "allocator_api", issue = "32838")]
541+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
516542
#[must_use]
517543
#[inline(always)]
518-
pub fn pin_in(x: T, alloc: A) -> Pin<Self>
544+
pub const fn pin_in(x: T, alloc: A) -> Pin<Self>
519545
where
520-
A: 'static,
546+
A: 'static + ~const Allocator + ~const Drop,
521547
{
522-
Self::new_in(x, alloc).into()
548+
Self::into_pin(Self::new_in(x, alloc))
523549
}
524550

525551
/// Converts a `Box<T>` into a `Box<[T]>`
526552
///
527553
/// This conversion does not allocate on the heap and happens in place.
528554
#[unstable(feature = "box_into_boxed_slice", issue = "71582")]
529-
pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
555+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
556+
pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
530557
let (raw, alloc) = Box::into_raw_with_allocator(boxed);
531558
unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) }
532559
}
@@ -543,8 +570,12 @@ impl<T, A: Allocator> Box<T, A> {
543570
/// assert_eq!(Box::into_inner(c), 5);
544571
/// ```
545572
#[unstable(feature = "box_into_inner", issue = "80437")]
573+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
546574
#[inline]
547-
pub fn into_inner(boxed: Self) -> T {
575+
pub const fn into_inner(boxed: Self) -> T
576+
where
577+
Self: ~const Drop,
578+
{
548579
*boxed
549580
}
550581
}
@@ -758,8 +789,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
758789
/// assert_eq!(*five, 5)
759790
/// ```
760791
#[unstable(feature = "new_uninit", issue = "63291")]
792+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
761793
#[inline]
762-
pub unsafe fn assume_init(self) -> Box<T, A> {
794+
pub const unsafe fn assume_init(self) -> Box<T, A> {
763795
let (raw, alloc) = Box::into_raw_with_allocator(self);
764796
unsafe { Box::from_raw_in(raw as *mut T, alloc) }
765797
}
@@ -792,8 +824,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
792824
/// }
793825
/// ```
794826
#[unstable(feature = "new_uninit", issue = "63291")]
827+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
795828
#[inline]
796-
pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
829+
pub const fn write(mut boxed: Self, value: T) -> Box<T, A> {
797830
unsafe {
798831
(*boxed).write(value);
799832
boxed.assume_init()
@@ -938,8 +971,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
938971
/// [memory layout]: self#memory-layout
939972
/// [`Layout`]: crate::Layout
940973
#[unstable(feature = "allocator_api", issue = "32838")]
974+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
941975
#[inline]
942-
pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
976+
pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
943977
Box(unsafe { Unique::new_unchecked(raw) }, alloc)
944978
}
945979

@@ -1035,8 +1069,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
10351069
///
10361070
/// [memory layout]: self#memory-layout
10371071
#[unstable(feature = "allocator_api", issue = "32838")]
1072+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
10381073
#[inline]
1039-
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
1074+
pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
10401075
let (leaked, alloc) = Box::into_unique(b);
10411076
(leaked.as_ptr(), alloc)
10421077
}
@@ -1046,9 +1081,10 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
10461081
issue = "none",
10471082
reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead"
10481083
)]
1084+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
10491085
#[inline]
10501086
#[doc(hidden)]
1051-
pub fn into_unique(b: Self) -> (Unique<T>, A) {
1087+
pub const fn into_unique(b: Self) -> (Unique<T>, A) {
10521088
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
10531089
// raw pointer for the type system. Turning it directly into a raw pointer would not be
10541090
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
@@ -1064,8 +1100,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
10641100
/// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This
10651101
/// is so that there is no conflict with a method on the inner type.
10661102
#[unstable(feature = "allocator_api", issue = "32838")]
1103+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
10671104
#[inline]
1068-
pub fn allocator(b: &Self) -> &A {
1105+
pub const fn allocator(b: &Self) -> &A {
10691106
&b.1
10701107
}
10711108

@@ -1105,8 +1142,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11051142
/// assert_eq!(*static_ref, [4, 2, 3]);
11061143
/// ```
11071144
#[stable(feature = "box_leak", since = "1.26.0")]
1145+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
11081146
#[inline]
1109-
pub fn leak<'a>(b: Self) -> &'a mut T
1147+
pub const fn leak<'a>(b: Self) -> &'a mut T
11101148
where
11111149
A: 'a,
11121150
{
@@ -1119,7 +1157,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11191157
///
11201158
/// This is also available via [`From`].
11211159
#[unstable(feature = "box_into_pin", issue = "62370")]
1122-
pub fn into_pin(boxed: Self) -> Pin<Self>
1160+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
1161+
pub const fn into_pin(boxed: Self) -> Pin<Self>
11231162
where
11241163
A: 'static,
11251164
{
@@ -1131,7 +1170,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11311170
}
11321171

11331172
#[stable(feature = "rust1", since = "1.0.0")]
1134-
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> {
1173+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
1174+
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> const Drop for Box<T, A> {
11351175
fn drop(&mut self) {
11361176
// FIXME: Do nothing, drop is currently performed by compiler.
11371177
}
@@ -1341,7 +1381,8 @@ impl<T> From<T> for Box<T> {
13411381
}
13421382

13431383
#[stable(feature = "pin", since = "1.33.0")]
1344-
impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
1384+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
1385+
impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>>
13451386
where
13461387
A: 'static,
13471388
{
@@ -1720,7 +1761,8 @@ impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> {
17201761
}
17211762

17221763
#[stable(feature = "rust1", since = "1.0.0")]
1723-
impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
1764+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
1765+
impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> {
17241766
type Target = T;
17251767

17261768
fn deref(&self) -> &T {
@@ -1729,7 +1771,8 @@ impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
17291771
}
17301772

17311773
#[stable(feature = "rust1", since = "1.0.0")]
1732-
impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
1774+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
1775+
impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A> {
17331776
fn deref_mut(&mut self) -> &mut T {
17341777
&mut **self
17351778
}
@@ -1908,7 +1951,8 @@ impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
19081951
* could have a method to project a Pin<T> from it.
19091952
*/
19101953
#[stable(feature = "pin", since = "1.33.0")]
1911-
impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
1954+
#[rustc_const_unstable(feature = "const_box", issue = "none")]
1955+
impl<T: ?Sized, A: Allocator> const Unpin for Box<T, A> where A: 'static {}
19121956

19131957
#[unstable(feature = "generator_trait", issue = "43122")]
19141958
impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A>

Diff for: library/alloc/src/lib.rs

+15
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,18 @@
9797
#![feature(async_stream)]
9898
#![feature(coerce_unsized)]
9999
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))]
100+
#![feature(const_box)]
100101
#![feature(const_cow_is_borrowed)]
102+
#![feature(const_convert)]
103+
#![feature(const_size_of_val)]
104+
#![feature(const_align_of_val)]
105+
#![feature(const_ptr_read)]
106+
#![feature(const_maybe_uninit_write)]
107+
#![feature(const_maybe_uninit_as_mut_ptr)]
108+
#![feature(const_refs_to_cell)]
101109
#![feature(core_intrinsics)]
110+
#![feature(const_eval_select)]
111+
#![feature(const_pin)]
102112
#![feature(dispatch_from_dyn)]
103113
#![feature(exact_size_is_empty)]
104114
#![feature(extend_one)]
@@ -134,8 +144,13 @@
134144
#![feature(box_syntax)]
135145
#![feature(cfg_sanitize)]
136146
#![feature(cfg_target_has_atomic)]
147+
#![feature(const_deref)]
137148
#![feature(const_fn_trait_bound)]
149+
#![feature(const_mut_refs)]
150+
#![feature(const_ptr_write)]
151+
#![feature(const_precise_live_drops)]
138152
#![feature(const_trait_impl)]
153+
#![feature(const_try)]
139154
#![cfg_attr(bootstrap, feature(destructuring_assignment))]
140155
#![feature(dropck_eyepatch)]
141156
#![feature(exclusive_range_pattern)]

0 commit comments

Comments
 (0)