Skip to content

Commit 649cfef

Browse files
authored
Rollup merge of #155795 - Lars-Schumann:const-vec-macro, r=oli-obk
constify `vec![1, 2, 3]` macro Tracking issues: `const_heap`: #79597 makes all the parts needed for non-empty `vec![]` macros const: `alloc::boxed::box_assume_init_into_vec_unsafe` `alloc::boxed::Box::assume_init` `alloc::boxed::Box::into_raw_with_allocator` `alloc::boxed::Box::new_uninit` `alloc::slice::[T]::into_vec` Note that this does not allow for the use of the `vec![(); 4]` arm of this macro to be used in const-eval, since that uses specialization (spec and const traits don't really like each other so I didn't want to touch any of that in this).
2 parents 59906a3 + b1342c9 commit 649cfef

8 files changed

Lines changed: 57 additions & 184 deletions

File tree

library/alloc/src/boxed.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ pub struct Box<
246246
#[rustc_no_mir_inline]
247247
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
248248
#[cfg(not(no_global_oom_handling))]
249-
fn box_new_uninit(layout: Layout) -> *mut u8 {
249+
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
250+
const fn box_new_uninit(layout: Layout) -> *mut u8 {
250251
match Global.allocate(layout) {
251252
Ok(ptr) => ptr.as_mut_ptr(),
252253
Err(_) => handle_alloc_error(layout),
@@ -258,10 +259,11 @@ fn box_new_uninit(layout: Layout) -> *mut u8 {
258259
/// This is unsafe, but has to be marked as safe or else we couldn't use it in `vec!`.
259260
#[doc(hidden)]
260261
#[unstable(feature = "liballoc_internals", issue = "none")]
262+
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
261263
#[inline(always)]
262264
#[cfg(not(no_global_oom_handling))]
263265
#[rustc_diagnostic_item = "box_assume_init_into_vec_unsafe"]
264-
pub fn box_assume_init_into_vec_unsafe<T, const N: usize>(
266+
pub const fn box_assume_init_into_vec_unsafe<T, const N: usize>(
265267
b: Box<MaybeUninit<[T; N]>>,
266268
) -> crate::vec::Vec<T> {
267269
unsafe { (b.assume_init() as Box<[T]>).into_vec() }
@@ -307,10 +309,11 @@ impl<T> Box<T> {
307309
/// ```
308310
#[cfg(not(no_global_oom_handling))]
309311
#[stable(feature = "new_uninit", since = "1.82.0")]
312+
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
310313
#[must_use]
311314
#[inline(always)]
312315
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
313-
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
316+
pub const fn new_uninit() -> Box<mem::MaybeUninit<T>> {
314317
// This is the same as `Self::new_uninit_in(Global)`, but manually inlined (just like
315318
// `Box::new`).
316319

@@ -1197,8 +1200,9 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
11971200
/// assert_eq!(*five, 5)
11981201
/// ```
11991202
#[stable(feature = "new_uninit", since = "1.82.0")]
1203+
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
12001204
#[inline(always)]
1201-
pub unsafe fn assume_init(self) -> Box<T, A> {
1205+
pub const unsafe fn assume_init(self) -> Box<T, A> {
12021206
// This is used in the `vec!` macro, so we optimize for minimal IR generation
12031207
// even in debug builds.
12041208
// SAFETY: `Box<T>` and `Box<MaybeUninit<T>>` have the same layout.
@@ -1668,8 +1672,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
16681672
/// [memory layout]: self#memory-layout
16691673
#[must_use = "losing the pointer will leak memory"]
16701674
#[unstable(feature = "allocator_api", issue = "32838")]
1675+
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
16711676
#[inline]
1672-
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
1677+
pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
16731678
let mut b = mem::ManuallyDrop::new(b);
16741679
// We carefully get the raw pointer out in a way that Miri's aliasing model understands what
16751680
// is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we

library/alloc/src/slice.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,9 @@ impl<T> [T] {
476476
/// ```
477477
#[rustc_allow_incoherent_impl]
478478
#[stable(feature = "rust1", since = "1.0.0")]
479+
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
479480
#[inline]
480-
pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
481+
pub const fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
481482
unsafe {
482483
let len = self.len();
483484
let (b, alloc) = Box::into_raw_with_allocator(self);

library/alloctests/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#![feature(binary_heap_pop_if)]
99
#![feature(casefold)]
1010
#![feature(const_btree_len)]
11+
#![feature(const_cmp)]
1112
#![feature(const_heap)]
1213
#![feature(const_trait_impl)]
1314
#![feature(core_intrinsics)]

library/alloctests/tests/vec.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2807,3 +2807,26 @@ fn const_make_global_empty_or_zst_regression() {
28072807

28082808
assert_eq!(ZST_SLICE, &[(), (), ()]);
28092809
}
2810+
2811+
#[test]
2812+
fn const_heap_vec_macro() {
2813+
const X: &'static [u32] = {
2814+
let x: Vec<u32> = vec![];
2815+
assert!(x == []);
2816+
x.const_make_global()
2817+
};
2818+
2819+
const Y: &'static [u32] = {
2820+
let y: Vec<u32> = vec![1, 2, 3];
2821+
assert!(y == [1, 2, 3]);
2822+
y.const_make_global()
2823+
};
2824+
2825+
// This arm isn't const yet.
2826+
// const Z: &'static [u32] = {
2827+
// vec![4; 2].const_make_global()
2828+
// };
2829+
2830+
assert_eq!(X, []);
2831+
assert_eq!(Y, [1, 2, 3]);
2832+
}

tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests/ui/statics/check-values-constraints.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Verifies all possible restrictions for statics values.
22

3+
#![feature(const_heap)]
34
#![allow(warnings)]
45

56
use std::marker;
@@ -79,8 +80,6 @@ static STATIC10: UnsafeStruct = UnsafeStruct;
7980
struct MyOwned;
8081

8182
static STATIC11: Vec<MyOwned> = vec![MyOwned];
82-
//~^ ERROR cannot call non-const function
83-
//~| ERROR cannot call non-const
8483

8584
static mut STATIC12: UnsafeStruct = UnsafeStruct;
8685

@@ -93,29 +92,25 @@ static mut STATIC14: SafeStruct = SafeStruct {
9392
};
9493

9594
static STATIC15: &'static [Vec<MyOwned>] = &[
96-
vec![MyOwned], //~ ERROR cannot call non-const function
97-
//~| ERROR cannot call non-const
98-
vec![MyOwned], //~ ERROR cannot call non-const function
99-
//~| ERROR cannot call non-const
95+
vec![MyOwned],
96+
vec![MyOwned],
10097
];
10198

10299
static STATIC16: (&'static Vec<MyOwned>, &'static Vec<MyOwned>) = (
103-
&vec![MyOwned], //~ ERROR cannot call non-const function
104-
//~| ERROR cannot call non-const
105-
&vec![MyOwned], //~ ERROR cannot call non-const function
106-
//~| ERROR cannot call non-const
100+
&vec![MyOwned],
101+
&vec![MyOwned],
107102
);
108103

109104
static mut STATIC17: SafeEnum = SafeEnum::Variant1;
110105

111106
static STATIC19: Vec<isize> = vec![3];
112-
//~^ ERROR cannot call non-const function
113-
//~| ERROR cannot call non-const
107+
//~^ ERROR encountered `const_allocate` pointer in final value that was not made global
108+
114109

115110
pub fn main() {
116111
let y = {
117-
static x: Vec<isize> = vec![3]; //~ ERROR cannot call non-const function
118-
//~| ERROR cannot call non-const
112+
static x: Vec<isize> = vec![3];
113+
//~^ ERROR encountered `const_allocate` pointer in final value that was not made global
119114
x
120115
//~^ ERROR cannot move out of static
121116
};
Lines changed: 12 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0493]: destructor of `SafeStruct` cannot be evaluated at compile-time
2-
--> $DIR/check-values-constraints.rs:64:7
2+
--> $DIR/check-values-constraints.rs:65:7
33
|
44
LL | ..SafeStruct {
55
| _______^
@@ -11,28 +11,8 @@ LL | | }
1111
LL | };
1212
| - value is dropped here
1313

14-
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
15-
--> $DIR/check-values-constraints.rs:81:33
16-
|
17-
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
18-
| ^^^^^^^^^^^^^
19-
|
20-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
21-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
22-
23-
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
24-
--> $DIR/check-values-constraints.rs:81:33
25-
|
26-
LL | static STATIC11: Vec<MyOwned> = vec![MyOwned];
27-
| ^^^^^^^^^^^^^
28-
|
29-
note: function `box_assume_init_into_vec_unsafe` is not const
30-
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
31-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
32-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
33-
3414
error[E0015]: cannot call non-const method `<str as ToString>::to_string` in statics
35-
--> $DIR/check-values-constraints.rs:92:38
15+
--> $DIR/check-values-constraints.rs:91:38
3616
|
3717
LL | field2: SafeEnum::Variant4("str".to_string()),
3818
| ^^^^^^^^^^^
@@ -47,128 +27,24 @@ note: method `to_string` is not const because trait `ToString` is not const
4727
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
4828
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
4929

50-
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
51-
--> $DIR/check-values-constraints.rs:96:5
52-
|
53-
LL | vec![MyOwned],
54-
| ^^^^^^^^^^^^^
55-
|
56-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
57-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
58-
59-
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
60-
--> $DIR/check-values-constraints.rs:96:5
61-
|
62-
LL | vec![MyOwned],
63-
| ^^^^^^^^^^^^^
64-
|
65-
note: function `box_assume_init_into_vec_unsafe` is not const
66-
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
67-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
68-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
69-
70-
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
71-
--> $DIR/check-values-constraints.rs:98:5
72-
|
73-
LL | vec![MyOwned],
74-
| ^^^^^^^^^^^^^
75-
|
76-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
77-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
78-
79-
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
80-
--> $DIR/check-values-constraints.rs:98:5
81-
|
82-
LL | vec![MyOwned],
83-
| ^^^^^^^^^^^^^
84-
|
85-
note: function `box_assume_init_into_vec_unsafe` is not const
86-
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
87-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
88-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
89-
90-
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
91-
--> $DIR/check-values-constraints.rs:103:6
92-
|
93-
LL | &vec![MyOwned],
94-
| ^^^^^^^^^^^^^
95-
|
96-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
97-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
98-
99-
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
100-
--> $DIR/check-values-constraints.rs:103:6
101-
|
102-
LL | &vec![MyOwned],
103-
| ^^^^^^^^^^^^^
104-
|
105-
note: function `box_assume_init_into_vec_unsafe` is not const
106-
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
107-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
108-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
109-
110-
error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics
111-
--> $DIR/check-values-constraints.rs:105:6
112-
|
113-
LL | &vec![MyOwned],
114-
| ^^^^^^^^^^^^^
115-
|
116-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
117-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
118-
119-
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<MyOwned, 1>` in statics
120-
--> $DIR/check-values-constraints.rs:105:6
121-
|
122-
LL | &vec![MyOwned],
123-
| ^^^^^^^^^^^^^
124-
|
125-
note: function `box_assume_init_into_vec_unsafe` is not const
126-
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
127-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
128-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
129-
130-
error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics
131-
--> $DIR/check-values-constraints.rs:111:31
30+
error: encountered `const_allocate` pointer in final value that was not made global
31+
--> $DIR/check-values-constraints.rs:106:1
13232
|
13333
LL | static STATIC19: Vec<isize> = vec![3];
134-
| ^^^^^^^
34+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
13535
|
136-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
137-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
138-
139-
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<isize, 1>` in statics
140-
--> $DIR/check-values-constraints.rs:111:31
141-
|
142-
LL | static STATIC19: Vec<isize> = vec![3];
143-
| ^^^^^^^
144-
|
145-
note: function `box_assume_init_into_vec_unsafe` is not const
146-
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
147-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
148-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
36+
= note: use `const_make_global` to turn allocated pointers into immutable globals before returning
14937

150-
error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics
151-
--> $DIR/check-values-constraints.rs:117:32
38+
error: encountered `const_allocate` pointer in final value that was not made global
39+
--> $DIR/check-values-constraints.rs:112:9
15240
|
15341
LL | static x: Vec<isize> = vec![3];
154-
| ^^^^^^^
42+
| ^^^^^^^^^^^^^^^^^^^^
15543
|
156-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
157-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
158-
159-
error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::<isize, 1>` in statics
160-
--> $DIR/check-values-constraints.rs:117:32
161-
|
162-
LL | static x: Vec<isize> = vec![3];
163-
| ^^^^^^^
164-
|
165-
note: function `box_assume_init_into_vec_unsafe` is not const
166-
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
167-
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
168-
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
44+
= note: use `const_make_global` to turn allocated pointers into immutable globals before returning
16945

17046
error[E0507]: cannot move out of static item `x`
171-
--> $DIR/check-values-constraints.rs:119:9
47+
--> $DIR/check-values-constraints.rs:114:9
17248
|
17349
LL | x
17450
| ^ move occurs because `x` has type `Vec<isize>`, which does not implement the `Copy` trait
@@ -182,7 +58,7 @@ help: consider cloning the value if the performance cost is acceptable
18258
LL | x.clone()
18359
| ++++++++
18460

185-
error: aborting due to 17 previous errors
61+
error: aborting due to 5 previous errors
18662

18763
Some errors have detailed explanations: E0015, E0493, E0507.
18864
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)