Const-stabilize Vec::new
.
This commit is contained in:
parent
b6269f27d9
commit
d5fe5831ec
6 changed files with 33 additions and 17 deletions
|
@ -117,7 +117,7 @@
|
||||||
#![feature(allocator_internals)]
|
#![feature(allocator_internals)]
|
||||||
#![feature(on_unimplemented)]
|
#![feature(on_unimplemented)]
|
||||||
#![feature(rustc_const_unstable)]
|
#![feature(rustc_const_unstable)]
|
||||||
#![feature(const_vec_new)]
|
#![cfg_attr(bootstrap, feature(const_vec_new))]
|
||||||
#![feature(slice_partition_dedup)]
|
#![feature(slice_partition_dedup)]
|
||||||
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
|
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
|
||||||
#![feature(alloc_layout_extra)]
|
#![feature(alloc_layout_extra)]
|
||||||
|
|
|
@ -113,13 +113,38 @@ impl<T, A: Alloc> RawVec<T, A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> RawVec<T, Global> {
|
impl<T> RawVec<T, Global> {
|
||||||
|
/// HACK(Centril): This exists because `#[unstable]` `const fn`s needn't conform
|
||||||
|
/// to `min_const_fn` and so they cannot be called in `min_const_fn`s either.
|
||||||
|
///
|
||||||
|
/// If you change `RawVec<T>::new` or dependencies, please take care to not
|
||||||
|
/// introduce anything that would truly violate `min_const_fn`.
|
||||||
|
///
|
||||||
|
/// NOTE: We could avoid this hack and check conformance with some
|
||||||
|
/// `#[rustc_force_min_const_fn]` attribute which requires conformance
|
||||||
|
/// with `min_const_fn` but does not necessarily allow calling it in
|
||||||
|
/// `stable(...) const fn` / user code not enabling `foo` when
|
||||||
|
/// `#[rustc_const_unstable(feature = "foo", ..)]` is present.
|
||||||
|
pub const NEW: Self = Self::new();
|
||||||
|
|
||||||
/// Creates the biggest possible `RawVec` (on the system heap)
|
/// Creates the biggest possible `RawVec` (on the system heap)
|
||||||
/// without allocating. If `T` has positive size, then this makes a
|
/// without allocating. If `T` has positive size, then this makes a
|
||||||
/// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
|
/// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
|
||||||
/// `RawVec` with capacity `usize::MAX`. Useful for implementing
|
/// `RawVec` with capacity `usize::MAX`. Useful for implementing
|
||||||
/// delayed allocation.
|
/// delayed allocation.
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self::new_in(Global)
|
// FIXME(Centril): Reintegrate this with `fn new_in` when we can.
|
||||||
|
|
||||||
|
// `!0` is `usize::MAX`. This branch should be stripped at compile time.
|
||||||
|
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
|
||||||
|
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
|
||||||
|
|
||||||
|
// `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
|
||||||
|
RawVec {
|
||||||
|
ptr: Unique::empty(),
|
||||||
|
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
|
||||||
|
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
|
||||||
|
a: Global,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a `RawVec` (on the system heap) with exactly the
|
/// Creates a `RawVec` (on the system heap) with exactly the
|
||||||
|
|
|
@ -314,10 +314,10 @@ impl<T> Vec<T> {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_vec_new")]
|
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_vec_new"))]
|
||||||
pub const fn new() -> Vec<T> {
|
pub const fn new() -> Vec<T> {
|
||||||
Vec {
|
Vec {
|
||||||
buf: RawVec::new(),
|
buf: RawVec::NEW,
|
||||||
len: 0,
|
len: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#![allow(dead_code)]
|
|
||||||
// Test several functions can be used for constants
|
// Test several functions can be used for constants
|
||||||
// 1. Vec::new()
|
// 1. Vec::new()
|
||||||
// 2. String::new()
|
// 2. String::new()
|
||||||
|
|
||||||
#![feature(const_vec_new)]
|
|
||||||
#![feature(const_string_new)]
|
#![feature(const_string_new)]
|
||||||
|
|
||||||
const MY_VEC: Vec<usize> = Vec::new();
|
const MY_VEC: Vec<usize> = Vec::new();
|
||||||
|
|
||||||
const MY_STRING: String = String::new();
|
const MY_STRING: String = String::new();
|
||||||
|
|
||||||
pub fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -14,8 +14,9 @@ trait Bar<T, U: Foo<T>> {
|
||||||
impl Foo<u32> for () {
|
impl Foo<u32> for () {
|
||||||
const X: u32 = 42;
|
const X: u32 = 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Foo<Vec<u32>> for String {
|
impl Foo<Vec<u32>> for String {
|
||||||
const X: Vec<u32> = Vec::new(); //~ ERROR not yet stable as a const fn
|
const X: Vec<u32> = Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bar<u32, ()> for () {}
|
impl Bar<u32, ()> for () {}
|
||||||
|
|
|
@ -4,13 +4,5 @@ error[E0493]: destructors cannot be evaluated at compile-time
|
||||||
LL | const F: u32 = (U::X, 42).1;
|
LL | const F: u32 = (U::X, 42).1;
|
||||||
| ^^^^^^^^^^ constants cannot evaluate destructors
|
| ^^^^^^^^^^ constants cannot evaluate destructors
|
||||||
|
|
||||||
error: `std::vec::Vec::<T>::new` is not yet stable as a const fn
|
error: aborting due to previous error
|
||||||
--> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25
|
|
||||||
|
|
|
||||||
LL | const X: Vec<u32> = Vec::new();
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: add `#![feature(const_vec_new)]` to the crate attributes to enable
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue