Skip to content

Commit b88c152

Browse files
authored
Rollup merge of rust-lang#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 rust-lang#49146 is done...
2 parents 64e6dda + f9f9923 commit b88c152

File tree

5 files changed

+28
-8
lines changed

5 files changed

+28
-8
lines changed

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
#![feature(pointer_methods)]
125125
#![feature(inclusive_range_fields)]
126126
#![cfg_attr(stage0, feature(generic_param_attrs))]
127+
#![feature(rustc_const_unstable)]
127128

128129
#![cfg_attr(not(test), feature(fn_traits, i128))]
129130
#![cfg_attr(test, feature(test))]

src/liballoc/raw_vec.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,16 @@ pub struct RawVec<T, A: Alloc = Global> {
5656
impl<T, A: Alloc> RawVec<T, A> {
5757
/// Like `new` but parameterized over the choice of allocator for
5858
/// the returned RawVec.
59-
pub fn new_in(a: A) -> Self {
59+
pub const fn new_in(a: A) -> Self {
6060
// !0 is usize::MAX. This branch should be stripped at compile time.
61-
let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
61+
// FIXME(mark-i-m): use this line when `if`s are allowed in `const`
62+
//let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
6263

6364
// Unique::empty() doubles as "unallocated" and "zero-sized allocation"
6465
RawVec {
6566
ptr: Unique::empty(),
66-
cap,
67+
// FIXME(mark-i-m): use `cap` when ifs are allowed in const
68+
cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
6769
a,
6870
}
6971
}
@@ -120,7 +122,7 @@ impl<T> RawVec<T, Global> {
120122
/// RawVec with capacity 0. If T has 0 size, then it makes a
121123
/// RawVec with capacity `usize::MAX`. Useful for implementing
122124
/// delayed allocation.
123-
pub fn new() -> Self {
125+
pub const fn new() -> Self {
124126
Self::new_in(Global)
125127
}
126128

src/liballoc/vec.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ impl<T> Vec<T> {
322322
/// ```
323323
#[inline]
324324
#[stable(feature = "rust1", since = "1.0.0")]
325-
pub fn new() -> Vec<T> {
325+
#[rustc_const_unstable(feature = "const_vec_new")]
326+
pub const fn new() -> Vec<T> {
326327
Vec {
327328
buf: RawVec::new(),
328329
len: 0,

src/libcore/ptr.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2552,10 +2552,9 @@ impl<T: Sized> Unique<T> {
25522552
/// This is useful for initializing types which lazily allocate, like
25532553
/// `Vec::new` does.
25542554
// FIXME: rename to dangling() to match NonNull?
2555-
pub fn empty() -> Self {
2555+
pub const fn empty() -> Self {
25562556
unsafe {
2557-
let ptr = mem::align_of::<T>() as *mut T;
2558-
Unique::new_unchecked(ptr)
2557+
Unique::new_unchecked(mem::align_of::<T>() as *mut T)
25592558
}
25602559
}
25612560
}

src/test/run-pass/vec-const-new.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that Vec::new() can be used for constants
12+
13+
#![feature(const_vec_new)]
14+
15+
const MY_VEC: Vec<usize> = Vec::new();
16+
17+
pub fn main() {}

0 commit comments

Comments
 (0)