Skip to content

Commit be327a8

Browse files
authored
Rollup merge of rust-lang#64028 - Centril:stabilize-alloc-new-2, r=alexcrichton
Stabilize `Vec::new` and `String::new` as `const fn`s Closes rust-lang#64022. r? @oli-obk
2 parents f432d50 + 9b3e11f commit be327a8

7 files changed

+35
-21
lines changed

src/liballoc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
#![feature(allocator_internals)]
118118
#![feature(on_unimplemented)]
119119
#![feature(rustc_const_unstable)]
120-
#![feature(const_vec_new)]
120+
#![cfg_attr(bootstrap, feature(const_vec_new))]
121121
#![feature(slice_partition_dedup)]
122122
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
123123
#![feature(alloc_layout_extra)]

src/liballoc/raw_vec.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,38 @@ impl<T, A: Alloc> RawVec<T, A> {
113113
}
114114

115115
impl<T> RawVec<T, Global> {
116+
/// HACK(Centril): This exists because `#[unstable]` `const fn`s needn't conform
117+
/// to `min_const_fn` and so they cannot be called in `min_const_fn`s either.
118+
///
119+
/// If you change `RawVec<T>::new` or dependencies, please take care to not
120+
/// introduce anything that would truly violate `min_const_fn`.
121+
///
122+
/// NOTE: We could avoid this hack and check conformance with some
123+
/// `#[rustc_force_min_const_fn]` attribute which requires conformance
124+
/// with `min_const_fn` but does not necessarily allow calling it in
125+
/// `stable(...) const fn` / user code not enabling `foo` when
126+
/// `#[rustc_const_unstable(feature = "foo", ..)]` is present.
127+
pub const NEW: Self = Self::new();
128+
116129
/// Creates the biggest possible `RawVec` (on the system heap)
117130
/// without allocating. If `T` has positive size, then this makes a
118131
/// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
119132
/// `RawVec` with capacity `usize::MAX`. Useful for implementing
120133
/// delayed allocation.
121134
pub const fn new() -> Self {
122-
Self::new_in(Global)
135+
// FIXME(Centril): Reintegrate this with `fn new_in` when we can.
136+
137+
// `!0` is `usize::MAX`. This branch should be stripped at compile time.
138+
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
139+
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
140+
141+
// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
142+
RawVec {
143+
ptr: Unique::empty(),
144+
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
145+
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
146+
a: Global,
147+
}
123148
}
124149

125150
/// Creates a `RawVec` (on the system heap) with exactly the

src/liballoc/string.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ impl String {
369369
/// ```
370370
#[inline]
371371
#[stable(feature = "rust1", since = "1.0.0")]
372-
#[rustc_const_unstable(feature = "const_string_new")]
372+
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_string_new"))]
373373
pub const fn new() -> String {
374374
String { vec: Vec::new() }
375375
}

src/liballoc/vec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -314,10 +314,10 @@ impl<T> Vec<T> {
314314
/// ```
315315
#[inline]
316316
#[stable(feature = "rust1", since = "1.0.0")]
317-
#[rustc_const_unstable(feature = "const_vec_new")]
317+
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_vec_new"))]
318318
pub const fn new() -> Vec<T> {
319319
Vec {
320-
buf: RawVec::new(),
320+
buf: RawVec::NEW,
321321
len: 0,
322322
}
323323
}

src/test/ui/collections-const-new.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
// run-pass
1+
// check-pass
22

3-
#![allow(dead_code)]
43
// Test several functions can be used for constants
54
// 1. Vec::new()
65
// 2. String::new()
76

8-
#![feature(const_vec_new)]
9-
#![feature(const_string_new)]
10-
117
const MY_VEC: Vec<usize> = Vec::new();
128

139
const MY_STRING: String = String::new();
1410

15-
pub fn main() {}
11+
fn main() {}

src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ trait Bar<T, U: Foo<T>> {
1414
impl Foo<u32> for () {
1515
const X: u32 = 42;
1616
}
17+
1718
impl Foo<Vec<u32>> for String {
18-
const X: Vec<u32> = Vec::new(); //~ ERROR not yet stable as a const fn
19+
const X: Vec<u32> = Vec::new();
1920
}
2021

2122
impl Bar<u32, ()> for () {}

src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr

+1-9
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,5 @@ error[E0493]: destructors cannot be evaluated at compile-time
44
LL | const F: u32 = (U::X, 42).1;
55
| ^^^^^^^^^^ constants cannot evaluate destructors
66

7-
error: `std::vec::Vec::<T>::new` is not yet stable as a const fn
8-
--> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25
9-
|
10-
LL | const X: Vec<u32> = Vec::new();
11-
| ^^^^^^^^^^
12-
|
13-
= help: add `#![feature(const_vec_new)]` to the crate attributes to enable
14-
15-
error: aborting due to 2 previous errors
7+
error: aborting due to previous error
168

0 commit comments

Comments
 (0)