From d5fe5831ecc82d2705110810261b79ae4040c403 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 11:32:38 +0200 Subject: [PATCH 1/2] Const-stabilize `Vec::new`. --- src/liballoc/lib.rs | 2 +- src/liballoc/raw_vec.rs | 27 ++++++++++++++++++- src/liballoc/vec.rs | 4 +-- src/test/ui/collections-const-new.rs | 4 +-- ...ure-gate-unleash_the_miri_inside_of_you.rs | 3 ++- ...gate-unleash_the_miri_inside_of_you.stderr | 10 +------ 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 370e5cf4b303f..9e6ed92ffb567 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -117,7 +117,7 @@ #![feature(allocator_internals)] #![feature(on_unimplemented)] #![feature(rustc_const_unstable)] -#![feature(const_vec_new)] +#![cfg_attr(bootstrap, feature(const_vec_new))] #![feature(slice_partition_dedup)] #![feature(maybe_uninit_extra, maybe_uninit_slice)] #![feature(alloc_layout_extra)] diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index cf025eee4358b..ee75fc288fee5 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -113,13 +113,38 @@ impl RawVec { } impl RawVec { + /// 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::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) /// 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 `usize::MAX`. Useful for implementing /// delayed allocation. 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::() == 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::() == 0) as usize], + a: Global, + } } /// Creates a `RawVec` (on the system heap) with exactly the diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index c513658c842e5..405969a550b88 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -314,10 +314,10 @@ impl Vec { /// ``` #[inline] #[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 { Vec { - buf: RawVec::new(), + buf: RawVec::NEW, len: 0, } } diff --git a/src/test/ui/collections-const-new.rs b/src/test/ui/collections-const-new.rs index e01b0dfa14d6e..15c5c65ff81f3 100644 --- a/src/test/ui/collections-const-new.rs +++ b/src/test/ui/collections-const-new.rs @@ -1,15 +1,13 @@ // run-pass -#![allow(dead_code)] // Test several functions can be used for constants // 1. Vec::new() // 2. String::new() -#![feature(const_vec_new)] #![feature(const_string_new)] const MY_VEC: Vec = Vec::new(); const MY_STRING: String = String::new(); -pub fn main() {} +fn main() {} diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs index 5fb92535502a5..8b17f6885ad3e 100644 --- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs +++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs @@ -14,8 +14,9 @@ trait Bar> { impl Foo for () { const X: u32 = 42; } + impl Foo> for String { - const X: Vec = Vec::new(); //~ ERROR not yet stable as a const fn + const X: Vec = Vec::new(); } impl Bar for () {} diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr index c56ebf60df481..5bc7b70638c80 100644 --- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr +++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr @@ -4,13 +4,5 @@ error[E0493]: destructors cannot be evaluated at compile-time LL | const F: u32 = (U::X, 42).1; | ^^^^^^^^^^ constants cannot evaluate destructors -error: `std::vec::Vec::::new` is not yet stable as a const fn - --> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25 - | -LL | const X: Vec = Vec::new(); - | ^^^^^^^^^^ - | - = help: add `#![feature(const_vec_new)]` to the crate attributes to enable - -error: aborting due to 2 previous errors +error: aborting due to previous error From 9b3e11f635c0354040ce515ac0ed4fade6fe928f Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 29 Aug 2019 12:36:07 +0200 Subject: [PATCH 2/2] Const-stabilize `String::new`. --- src/liballoc/string.rs | 2 +- src/test/ui/collections-const-new.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index b65f191836e9d..1166e7b5df295 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -369,7 +369,7 @@ impl String { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_string_new")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_string_new"))] pub const fn new() -> String { String { vec: Vec::new() } } diff --git a/src/test/ui/collections-const-new.rs b/src/test/ui/collections-const-new.rs index 15c5c65ff81f3..a93f9a136db23 100644 --- a/src/test/ui/collections-const-new.rs +++ b/src/test/ui/collections-const-new.rs @@ -1,11 +1,9 @@ -// run-pass +// check-pass // Test several functions can be used for constants // 1. Vec::new() // 2. String::new() -#![feature(const_string_new)] - const MY_VEC: Vec = Vec::new(); const MY_STRING: String = String::new();