Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ pub struct Box<
#[rustc_no_mir_inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[cfg(not(no_global_oom_handling))]
fn box_new_uninit(layout: Layout) -> *mut u8 {
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
const fn box_new_uninit(layout: Layout) -> *mut u8 {
match Global.allocate(layout) {
Ok(ptr) => ptr.as_mut_ptr(),
Err(_) => handle_alloc_error(layout),
Expand All @@ -258,10 +259,11 @@ fn box_new_uninit(layout: Layout) -> *mut u8 {
/// This is unsafe, but has to be marked as safe or else we couldn't use it in `vec!`.
#[doc(hidden)]
#[unstable(feature = "liballoc_internals", issue = "none")]
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
#[inline(always)]
#[cfg(not(no_global_oom_handling))]
#[rustc_diagnostic_item = "box_assume_init_into_vec_unsafe"]
pub fn box_assume_init_into_vec_unsafe<T, const N: usize>(
pub const fn box_assume_init_into_vec_unsafe<T, const N: usize>(
b: Box<MaybeUninit<[T; N]>>,
) -> crate::vec::Vec<T> {
unsafe { (b.assume_init() as Box<[T]>).into_vec() }
Expand Down Expand Up @@ -307,10 +309,11 @@ impl<T> Box<T> {
/// ```
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "new_uninit", since = "1.82.0")]
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
#[must_use]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
pub const fn new_uninit() -> Box<mem::MaybeUninit<T>> {
// This is the same as `Self::new_uninit_in(Global)`, but manually inlined (just like
// `Box::new`).

Expand Down Expand Up @@ -1197,8 +1200,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
/// assert_eq!(*five, 5)
/// ```
#[stable(feature = "new_uninit", since = "1.82.0")]
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
#[inline(always)]
pub unsafe fn assume_init(self) -> Box<T, A> {
pub const unsafe fn assume_init(self) -> Box<T, A> {
// This is used in the `vec!` macro, so we optimize for minimal IR generation
// even in debug builds.
// SAFETY: `Box<T>` and `Box<MaybeUninit<T>>` have the same layout.
Expand Down Expand Up @@ -1668,8 +1672,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
/// [memory layout]: self#memory-layout
#[must_use = "losing the pointer will leak memory"]
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
#[inline]
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
let mut b = mem::ManuallyDrop::new(b);
// We carefully get the raw pointer out in a way that Miri's aliasing model understands what
// is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we
Expand Down
3 changes: 2 additions & 1 deletion library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,8 +476,9 @@ impl<T> [T] {
/// ```
#[rustc_allow_incoherent_impl]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
#[inline]
pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
pub const fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
unsafe {
let len = self.len();
let (b, alloc) = Box::into_raw_with_allocator(self);
Expand Down
1 change: 1 addition & 0 deletions library/alloctests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#![feature(binary_heap_pop_if)]
#![feature(casefold)]
#![feature(const_btree_len)]
#![feature(const_cmp)]
#![feature(const_heap)]
#![feature(const_trait_impl)]
#![feature(core_intrinsics)]
Expand Down
23 changes: 23 additions & 0 deletions library/alloctests/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2807,3 +2807,26 @@ fn const_make_global_empty_or_zst_regression() {

assert_eq!(ZST_SLICE, &[(), (), ()]);
}

#[test]
fn const_heap_vec_macro() {
const X: &'static [u32] = {
let x: Vec<u32> = vec![];
assert!(x == []);
x.const_make_global()
};

const Y: &'static [u32] = {
let y: Vec<u32> = vec![1, 2, 3];
assert!(y == [1, 2, 3]);
y.const_make_global()
};

// This arm isn't const yet.
// const Z: &'static [u32] = {
// vec![4; 2].const_make_global()
// };

assert_eq!(X, []);
assert_eq!(Y, [1, 2, 3]);
}
9 changes: 6 additions & 3 deletions tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const fn foo(a: i32) -> Vec<i32> {
fn non_const() -> Vec<i32> {
vec![1, 2, 3]
//~^ ERROR cannot call non-const
//~| ERROR cannot call non-const
}

const fn foo(a: i32) -> Vec<i32> {
non_const()
//~^ ERROR cannot call non-const function
}

fn main() {}
23 changes: 9 additions & 14 deletions tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
error[E0015]: cannot call non-const associated function `Box::<[i32; 3]>::new_uninit` in constant functions
--> $DIR/bad_const_fn_body_ice.rs:2:5
error[E0015]: cannot call non-const function `non_const` in constant functions
--> $DIR/bad_const_fn_body_ice.rs:6:5
|
LL | vec![1, 2, 3]
| ^^^^^^^^^^^^^
LL | non_const()
| ^^^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<i32, 3>` in constant functions
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
LL | vec![1, 2, 3]
| ^^^^^^^^^^^^^
note: function `non_const` is not const
--> $DIR/bad_const_fn_body_ice.rs:1:1
|
note: function `box_assume_init_into_vec_unsafe` is not const
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
LL | fn non_const() -> Vec<i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0015`.
25 changes: 11 additions & 14 deletions tests/ui/statics/check-values-constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ static STATIC9: SafeStruct = SafeStruct {
}
};

fn non_const<T>(value: T) -> Vec<T> {
vec![value]
}

struct UnsafeStruct;

impl Drop for UnsafeStruct {
Expand All @@ -78,9 +82,8 @@ static STATIC10: UnsafeStruct = UnsafeStruct;

struct MyOwned;

static STATIC11: Vec<MyOwned> = vec![MyOwned];
static STATIC11: Vec<MyOwned> = non_const(MyOwned);
//~^ ERROR cannot call non-const function
//~| ERROR cannot call non-const

static mut STATIC12: UnsafeStruct = UnsafeStruct;

Expand All @@ -93,29 +96,23 @@ static mut STATIC14: SafeStruct = SafeStruct {
};

static STATIC15: &'static [Vec<MyOwned>] = &[
vec![MyOwned], //~ ERROR cannot call non-const function
//~| ERROR cannot call non-const
vec![MyOwned], //~ ERROR cannot call non-const function
//~| ERROR cannot call non-const
non_const(MyOwned), //~ ERROR cannot call non-const function
non_const(MyOwned), //~ ERROR cannot call non-const function
];

static STATIC16: (&'static Vec<MyOwned>, &'static Vec<MyOwned>) = (
&vec![MyOwned], //~ ERROR cannot call non-const function
//~| ERROR cannot call non-const
&vec![MyOwned], //~ ERROR cannot call non-const function
//~| ERROR cannot call non-const
&non_const(MyOwned), //~ ERROR cannot call non-const function
&non_const(MyOwned), //~ ERROR cannot call non-const function
);

static mut STATIC17: SafeEnum = SafeEnum::Variant1;

static STATIC19: Vec<isize> = vec![3];
static STATIC19: Vec<isize> = non_const(3);
//~^ ERROR cannot call non-const function
//~| ERROR cannot call non-const

pub fn main() {
let y = {
static x: Vec<isize> = vec![3]; //~ ERROR cannot call non-const function
//~| ERROR cannot call non-const
static x: Vec<isize> = non_const(3); //~ ERROR cannot call non-const function
x
//~^ ERROR cannot move out of static
};
Expand Down
Loading
Loading