From b5afa6807b868bc8bb2e6f972629769b150ffd41 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 14 Aug 2021 16:35:12 +0000 Subject: [PATCH] Constified `Default` implementations The libs-api team agrees to allow const_trait_impl to appear in the standard library as long as stable code cannot be broken (they are properly gated) this means if the compiler teams thinks it's okay, then it's okay. My priority on constifying would be: 1. Non-generic impls (e.g. Default) or generic impls with no bounds 2. Generic functions with bounds (that use const impls) 3. Generic impls with bounds 4. Impls for traits with associated types For people opening constification PRs: please cc me and/or oli-obk. --- library/alloc/src/lib.rs | 1 + library/alloc/src/string.rs | 3 ++- library/alloc/src/vec/mod.rs | 3 ++- library/alloc/tests/const_fns.rs | 26 +++++++++++++------------- library/alloc/tests/lib.rs | 1 + library/core/src/array/mod.rs | 3 ++- library/core/src/default.rs | 3 ++- library/core/src/hash/mod.rs | 3 ++- library/core/src/iter/sources/empty.rs | 3 ++- library/core/src/lib.rs | 1 + library/core/src/marker.rs | 3 ++- library/core/src/option.rs | 3 ++- library/core/src/slice/mod.rs | 6 ++++-- library/core/src/str/mod.rs | 3 ++- library/core/src/sync/atomic.rs | 9 ++++++--- library/std/src/lazy.rs | 3 ++- library/std/src/lib.rs | 1 + 17 files changed, 47 insertions(+), 28 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index d2ececaa9759..1a387f291ccf 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -95,6 +95,7 @@ #![feature(const_fn_trait_bound)] #![feature(cow_is_borrowed)] #![feature(const_cow_is_borrowed)] +#![feature(const_trait_impl)] #![feature(destructuring_assignment)] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 9aefd882af4e..6568d9f9907b 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2105,7 +2105,8 @@ impl_eq! { Cow<'a, str>, &'b str } impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for String { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for String { /// Creates an empty `String`. #[inline] fn default() -> String { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 933361d812cb..87a0d3718156 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2758,7 +2758,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Vec { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Vec { /// Creates an empty `Vec`. fn default() -> Vec { Vec::new() diff --git a/library/alloc/tests/const_fns.rs b/library/alloc/tests/const_fns.rs index b6ef3eee291f..da58ae92e112 100644 --- a/library/alloc/tests/const_fns.rs +++ b/library/alloc/tests/const_fns.rs @@ -1,16 +1,8 @@ -// Test several functions can be used for constants -// 1. Vec::new() -// 2. String::new() -// 3. BTreeMap::new() -// 4. BTreeSet::new() +// Test const functions in the library -#[allow(dead_code)] -pub const MY_VEC: Vec = Vec::new(); +use core::cmp::Ordering; -#[allow(dead_code)] -pub const MY_STRING: String = String::new(); - -// FIXME(fee1-dead) remove this struct once we put `K: ?const Ord` on BTreeMap::new. +// FIXME remove this struct once we put `K: ?const Ord` on BTreeMap::new. #[derive(PartialEq, Eq, PartialOrd)] pub struct MyType; @@ -32,7 +24,12 @@ impl const Ord for MyType { } } -use core::cmp::Ordering; +pub const MY_VEC: Vec = Vec::new(); +pub const MY_VEC2: Vec = Default::default(); + +pub const MY_STRING: String = String::new(); +pub const MY_STRING2: String = Default::default(); + use std::collections::{BTreeMap, BTreeSet}; pub const MY_BTREEMAP: BTreeMap = BTreeMap::new(); @@ -47,7 +44,10 @@ pub const SET_IS_EMPTY: bool = SET.is_empty(); #[test] fn test_const() { + assert_eq!(MY_VEC, MY_VEC2); + assert_eq!(MY_STRING, MY_STRING2); + assert_eq!(MAP_LEN, 0); assert_eq!(SET_LEN, 0); - assert!(MAP_IS_EMPTY && SET_IS_EMPTY) + assert!(MAP_IS_EMPTY && SET_IS_EMPTY); } diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 7284c05d5ff1..5767108d423c 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -24,6 +24,7 @@ #![feature(vec_spare_capacity)] #![feature(string_remove_matches)] #![feature(const_btree_new)] +#![feature(const_default_impls)] #![feature(const_trait_impl)] use std::collections::hash_map::DefaultHasher; diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 3bc9f71375cb..3c638e655dc9 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -280,7 +280,8 @@ macro_rules! array_impl_default { }; {$n:expr,} => { #[stable(since = "1.4.0", feature = "array_default")] - impl Default for [T; $n] { + #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] + impl const Default for [T; $n] { fn default() -> [T; $n] { [] } } }; diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 6400a9b85956..0ee8cd59ba4f 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -171,7 +171,8 @@ pub macro Default($item:item) { macro_rules! default_impl { ($t:ty, $v:expr, $doc:tt) => { #[stable(feature = "rust1", since = "1.0.0")] - impl Default for $t { + #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] + impl const Default for $t { #[inline] #[doc = $doc] fn default() -> $t { diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 9dbefe0822e3..510e233b4311 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -599,7 +599,8 @@ impl Clone for BuildHasherDefault { } #[stable(since = "1.7.0", feature = "build_hasher")] -impl Default for BuildHasherDefault { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for BuildHasherDefault { fn default() -> BuildHasherDefault { BuildHasherDefault(marker::PhantomData) } diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index 919c564f2872..a7d4646f5c59 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs @@ -85,7 +85,8 @@ impl Clone for Empty { // not #[derive] because that adds a Default bound on T, // which isn't necessary. #[stable(feature = "iter_empty", since = "1.2.0")] -impl Default for Empty { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Empty { fn default() -> Empty { Empty(marker::PhantomData) } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 37c3f8d4c16a..4ab7cc24a0d4 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -103,6 +103,7 @@ #![feature(const_type_id)] #![feature(const_type_name)] #![feature(const_unreachable_unchecked)] +#![feature(const_default_impls)] #![feature(duration_consts_2)] #![feature(ptr_metadata)] #![feature(slice_ptr_get)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index fb957348bebd..333f81ce4cfc 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -528,7 +528,8 @@ macro_rules! impls { } #[stable(feature = "rust1", since = "1.0.0")] - impl Default for $t { + #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] + impl const Default for $t { fn default() -> Self { Self } diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 3f9f04606b36..78f5954532ff 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1642,7 +1642,8 @@ impl Clone for Option { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Option { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Option { /// Returns [`None`][Option::None]. /// /// # Examples diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 51227d541154..361a9b03aebc 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3501,7 +3501,8 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for &[T] { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for &[T] { /// Creates an empty slice. fn default() -> Self { &[] @@ -3509,7 +3510,8 @@ impl Default for &[T] { } #[stable(feature = "mut_slice_default", since = "1.5.0")] -impl Default for &mut [T] { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for &mut [T] { /// Creates a mutable empty slice. fn default() -> Self { &mut [] diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index d4e30e65ef85..947afbdc68df 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2442,7 +2442,8 @@ impl AsRef<[u8]> for str { } #[stable(feature = "rust1", since = "1.0.0")] -impl Default for &str { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for &str { /// Creates an empty str #[inline] fn default() -> Self { diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index d908b6ecda35..d9de37e9c519 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -138,7 +138,8 @@ pub struct AtomicBool { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "rust1", since = "1.0.0")] -impl Default for AtomicBool { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for AtomicBool { /// Creates an `AtomicBool` initialized to `false`. #[inline] fn default() -> Self { @@ -168,7 +169,8 @@ pub struct AtomicPtr { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] -impl Default for AtomicPtr { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for AtomicPtr { /// Creates a null `AtomicPtr`. fn default() -> AtomicPtr { AtomicPtr::new(crate::ptr::null_mut()) @@ -1351,7 +1353,8 @@ macro_rules! atomic_int { pub const $atomic_init: $atomic_type = $atomic_type::new(0); #[$stable] - impl Default for $atomic_type { + #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] + impl const Default for $atomic_type { #[inline] fn default() -> Self { Self::new(Default::default()) diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs index 132733a05251..5afdb799f0c7 100644 --- a/library/std/src/lazy.rs +++ b/library/std/src/lazy.rs @@ -86,7 +86,8 @@ impl RefUnwindSafe for SyncOnceCell {} impl UnwindSafe for SyncOnceCell {} #[unstable(feature = "once_cell", issue = "74465")] -impl Default for SyncOnceCell { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for SyncOnceCell { /// Creates a new empty cell. /// /// # Example diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 43db3f910224..5e91a0cdbd6b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -255,6 +255,7 @@ #![feature(const_ipv6)] #![feature(const_raw_ptr_deref)] #![feature(const_socketaddr)] +#![feature(const_trait_impl)] #![feature(container_error_extra)] #![feature(core_intrinsics)] #![feature(custom_test_frameworks)]