1
Fork 0

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.
This commit is contained in:
Deadbeef 2021-08-14 16:35:12 +00:00
parent 3b5df01439
commit b5afa6807b
No known key found for this signature in database
GPG key ID: 027DF9338862ADDD
17 changed files with 47 additions and 28 deletions

View file

@ -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)]

View file

@ -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 {

View file

@ -2758,7 +2758,8 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Vec<T> {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for Vec<T> {
/// Creates an empty `Vec<T>`.
fn default() -> Vec<T> {
Vec::new()

View file

@ -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<usize> = 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<usize> = Vec::new();
pub const MY_VEC2: Vec<usize> = 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<MyType, MyType> = 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);
}

View file

@ -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;

View file

@ -280,7 +280,8 @@ macro_rules! array_impl_default {
};
{$n:expr,} => {
#[stable(since = "1.4.0", feature = "array_default")]
impl<T> Default for [T; $n] {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for [T; $n] {
fn default() -> [T; $n] { [] }
}
};

View file

@ -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 {

View file

@ -599,7 +599,8 @@ impl<H> Clone for BuildHasherDefault<H> {
}
#[stable(since = "1.7.0", feature = "build_hasher")]
impl<H> Default for BuildHasherDefault<H> {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<H> const Default for BuildHasherDefault<H> {
fn default() -> BuildHasherDefault<H> {
BuildHasherDefault(marker::PhantomData)
}

View file

@ -85,7 +85,8 @@ impl<T> Clone for Empty<T> {
// not #[derive] because that adds a Default bound on T,
// which isn't necessary.
#[stable(feature = "iter_empty", since = "1.2.0")]
impl<T> Default for Empty<T> {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for Empty<T> {
fn default() -> Empty<T> {
Empty(marker::PhantomData)
}

View file

@ -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)]

View file

@ -528,7 +528,8 @@ macro_rules! impls {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Default for $t<T> {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T: ?Sized> const Default for $t<T> {
fn default() -> Self {
Self
}

View file

@ -1642,7 +1642,8 @@ impl<T: Clone> Clone for Option<T> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Option<T> {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for Option<T> {
/// Returns [`None`][Option::None].
///
/// # Examples

View file

@ -3501,7 +3501,8 @@ where
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for &[T] {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for &[T] {
/// Creates an empty slice.
fn default() -> Self {
&[]
@ -3509,7 +3510,8 @@ impl<T> Default for &[T] {
}
#[stable(feature = "mut_slice_default", since = "1.5.0")]
impl<T> Default for &mut [T] {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for &mut [T] {
/// Creates a mutable empty slice.
fn default() -> Self {
&mut []

View file

@ -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 {

View file

@ -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<T> {
#[cfg(target_has_atomic_load_store = "ptr")]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for AtomicPtr<T> {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for AtomicPtr<T> {
/// Creates a null `AtomicPtr<T>`.
fn default() -> AtomicPtr<T> {
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())

View file

@ -86,7 +86,8 @@ impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SyncOnceCell<T> {}
impl<T: UnwindSafe> UnwindSafe for SyncOnceCell<T> {}
#[unstable(feature = "once_cell", issue = "74465")]
impl<T> Default for SyncOnceCell<T> {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for SyncOnceCell<T> {
/// Creates a new empty cell.
///
/// # Example

View file

@ -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)]