Rollup merge of #50233 - mark-i-m:const_vec, r=kennytm
Make `Vec::new` a `const fn`
`RawVec::empty/_in` are a hack. They're there because `if size_of::<T> == 0 { !0 } else { 0 }` is not allowed in `const` yet. However, because `RawVec` is unstable, the `empty/empty_in` constructors can be removed when #49146 is done...
This commit is contained in:
@@ -124,6 +124,7 @@
|
|||||||
#![feature(pointer_methods)]
|
#![feature(pointer_methods)]
|
||||||
#![feature(inclusive_range_fields)]
|
#![feature(inclusive_range_fields)]
|
||||||
#![cfg_attr(stage0, feature(generic_param_attrs))]
|
#![cfg_attr(stage0, feature(generic_param_attrs))]
|
||||||
|
#![feature(rustc_const_unstable)]
|
||||||
|
|
||||||
#![cfg_attr(not(test), feature(fn_traits, i128))]
|
#![cfg_attr(not(test), feature(fn_traits, i128))]
|
||||||
#![cfg_attr(test, feature(test))]
|
#![cfg_attr(test, feature(test))]
|
||||||
|
|||||||
@@ -56,14 +56,16 @@ pub struct RawVec<T, A: Alloc = Global> {
|
|||||||
impl<T, A: Alloc> RawVec<T, A> {
|
impl<T, A: Alloc> RawVec<T, A> {
|
||||||
/// Like `new` but parameterized over the choice of allocator for
|
/// Like `new` but parameterized over the choice of allocator for
|
||||||
/// the returned RawVec.
|
/// the returned RawVec.
|
||||||
pub fn new_in(a: A) -> Self {
|
pub const fn new_in(a: A) -> Self {
|
||||||
// !0 is usize::MAX. This branch should be stripped at compile time.
|
// !0 is usize::MAX. This branch should be stripped at compile time.
|
||||||
let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
|
// 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"
|
// Unique::empty() doubles as "unallocated" and "zero-sized allocation"
|
||||||
RawVec {
|
RawVec {
|
||||||
ptr: Unique::empty(),
|
ptr: Unique::empty(),
|
||||||
cap,
|
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
|
||||||
|
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
|
||||||
a,
|
a,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +122,7 @@ impl<T> RawVec<T, Global> {
|
|||||||
/// RawVec with capacity 0. If T has 0 size, then it makes a
|
/// RawVec with capacity 0. If T has 0 size, 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 fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self::new_in(Global)
|
Self::new_in(Global)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -322,7 +322,8 @@ impl<T> Vec<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn new() -> Vec<T> {
|
#[rustc_const_unstable(feature = "const_vec_new")]
|
||||||
|
pub const fn new() -> Vec<T> {
|
||||||
Vec {
|
Vec {
|
||||||
buf: RawVec::new(),
|
buf: RawVec::new(),
|
||||||
len: 0,
|
len: 0,
|
||||||
|
|||||||
@@ -2552,10 +2552,9 @@ impl<T: Sized> Unique<T> {
|
|||||||
/// This is useful for initializing types which lazily allocate, like
|
/// This is useful for initializing types which lazily allocate, like
|
||||||
/// `Vec::new` does.
|
/// `Vec::new` does.
|
||||||
// FIXME: rename to dangling() to match NonNull?
|
// FIXME: rename to dangling() to match NonNull?
|
||||||
pub fn empty() -> Self {
|
pub const fn empty() -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = mem::align_of::<T>() as *mut T;
|
Unique::new_unchecked(mem::align_of::<T>() as *mut T)
|
||||||
Unique::new_unchecked(ptr)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/test/run-pass/vec-const-new.rs
Normal file
17
src/test/run-pass/vec-const-new.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test that Vec::new() can be used for constants
|
||||||
|
|
||||||
|
#![feature(const_vec_new)]
|
||||||
|
|
||||||
|
const MY_VEC: Vec<usize> = Vec::new();
|
||||||
|
|
||||||
|
pub fn main() {}
|
||||||
Reference in New Issue
Block a user