diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 021395d0c824a..0493f92bc520d 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -124,6 +124,7 @@ #![feature(pointer_methods)] #![feature(inclusive_range_fields)] #![cfg_attr(stage0, feature(generic_param_attrs))] +#![feature(rustc_const_unstable)] #![cfg_attr(not(test), feature(fn_traits, i128))] #![cfg_attr(test, feature(test))] diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 7ef0a27fc7258..eb25ae1751170 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -56,14 +56,16 @@ pub struct RawVec { impl RawVec { /// Like `new` but parameterized over the choice of allocator for /// 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. - let cap = if mem::size_of::() == 0 { !0 } else { 0 }; + // FIXME(mark-i-m): use this line when `if`s are allowed in `const` + //let cap = if mem::size_of::() == 0 { !0 } else { 0 }; // Unique::empty() doubles as "unallocated" and "zero-sized allocation" RawVec { ptr: Unique::empty(), - cap, + // FIXME(mark-i-m): use `cap` when ifs are allowed in const + cap: [0, !0][(mem::size_of::() == 0) as usize], a, } } @@ -120,7 +122,7 @@ impl RawVec { /// RawVec with capacity 0. If T has 0 size, then it makes a /// RawVec with capacity `usize::MAX`. Useful for implementing /// delayed allocation. - pub fn new() -> Self { + pub const fn new() -> Self { Self::new_in(Global) } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index b184404c15bfd..35d0a69a05abe 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -322,7 +322,8 @@ impl Vec { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> Vec { + #[rustc_const_unstable(feature = "const_vec_new")] + pub const fn new() -> Vec { Vec { buf: RawVec::new(), len: 0, diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index c61bdfc9c4f37..5d0b675e8e4c5 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2552,10 +2552,9 @@ impl Unique { /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does. // FIXME: rename to dangling() to match NonNull? - pub fn empty() -> Self { + pub const fn empty() -> Self { unsafe { - let ptr = mem::align_of::() as *mut T; - Unique::new_unchecked(ptr) + Unique::new_unchecked(mem::align_of::() as *mut T) } } } diff --git a/src/test/run-pass/vec-const-new.rs b/src/test/run-pass/vec-const-new.rs new file mode 100644 index 0000000000000..62e2a36d7cc77 --- /dev/null +++ b/src/test/run-pass/vec-const-new.rs @@ -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 or the MIT license +// , 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 = Vec::new(); + +pub fn main() {}