Skip to content

Make Default const and add some const Default impls #134628

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@
#![feature(bstr_internals)]
#![feature(clone_to_uninit)]
#![feature(coerce_unsized)]
#![feature(const_default)]
#![feature(const_eval_select)]
#![feature(const_heap)]
#![feature(const_trait_impl)]
#![feature(core_intrinsics)]
#![feature(deprecated_suggestion)]
#![feature(deref_pure_trait)]
Expand Down
3 changes: 2 additions & 1 deletion library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2538,7 +2538,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", issue = "none")]
impl const Default for String {
/// Creates an empty `String`.
#[inline]
fn default() -> String {
Expand Down
3 changes: 2 additions & 1 deletion library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3790,7 +3790,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", issue = "none")]
impl<T> const Default for Vec<T> {
/// Creates an empty `Vec<T>`.
///
/// The vector will not allocate until elements are pushed onto it.
Expand Down
12 changes: 8 additions & 4 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@ impl<T: Copy> Clone for Cell<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Cell<T> {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl<T: ~const Default> const Default for Cell<T> {
/// Creates a `Cell<T>`, with the `Default` value for T.
#[inline]
fn default() -> Cell<T> {
Expand Down Expand Up @@ -1318,7 +1319,8 @@ impl<T: Clone> Clone for RefCell<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for RefCell<T> {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl<T: ~const Default> const Default for RefCell<T> {
/// Creates a `RefCell<T>`, with the `Default` value for T.
#[inline]
fn default() -> RefCell<T> {
Expand Down Expand Up @@ -2316,7 +2318,8 @@ impl<T: ?Sized> UnsafeCell<T> {
}

#[stable(feature = "unsafe_cell_default", since = "1.10.0")]
impl<T: Default> Default for UnsafeCell<T> {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl<T: ~const Default> const Default for UnsafeCell<T> {
/// Creates an `UnsafeCell`, with the `Default` value for T.
fn default() -> UnsafeCell<T> {
UnsafeCell::new(Default::default())
Expand Down Expand Up @@ -2423,7 +2426,8 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
}

#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
impl<T: Default> Default for SyncUnsafeCell<T> {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl<T: ~const Default> const Default for SyncUnsafeCell<T> {
/// Creates an `SyncUnsafeCell`, with the `Default` value for T.
fn default() -> SyncUnsafeCell<T> {
SyncUnsafeCell::new(Default::default())
Expand Down
5 changes: 4 additions & 1 deletion library/core/src/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ use crate::ascii::Char as AsciiChar;
/// ```
#[cfg_attr(not(test), rustc_diagnostic_item = "Default")]
#[stable(feature = "rust1", since = "1.0.0")]
#[const_trait]
#[rustc_const_unstable(feature = "const_default", issue = "none")]
#[rustc_trivial_field_reads]
pub trait Default: Sized {
/// Returns the "default value" for a type.
Expand Down Expand Up @@ -150,7 +152,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", issue = "none")]
impl const Default for $t {
#[inline(always)]
#[doc = $doc]
fn default() -> $t {
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/iter/sources/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,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", issue = "none")]
impl<T> const Default for Empty<T> {
fn default() -> Empty<T> {
Empty(marker::PhantomData)
}
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,8 @@ impl<T: ?Sized> Clone for PhantomData<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Default for PhantomData<T> {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl<T: ?Sized> const Default for PhantomData<T> {
fn default() -> Self {
Self
}
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2051,7 +2051,8 @@ where
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Option<T> {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl<T> const Default for Option<T> {
/// Returns [`None`][Option::None].
///
/// # Examples
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/ptr/alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ impl hash::Hash for Alignment {

/// Returns [`Alignment::MIN`], which is valid for any type.
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
impl Default for Alignment {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl const Default for Alignment {
fn default() -> Alignment {
Alignment::MIN
}
Expand Down
6 changes: 4 additions & 2 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4942,15 +4942,17 @@ where
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for &[T] {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl<T> const Default for &[T] {
/// Creates an empty slice.
fn default() -> Self {
&[]
}
}

#[stable(feature = "mut_slice_default", since = "1.5.0")]
impl<T> Default for &mut [T] {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl<T> const Default for &mut [T] {
/// Creates a mutable empty slice.
fn default() -> Self {
&mut []
Expand Down
6 changes: 4 additions & 2 deletions library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2971,7 +2971,8 @@ impl AsRef<[u8]> for str {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Default for &str {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl const Default for &str {
/// Creates an empty str
#[inline]
fn default() -> Self {
Expand All @@ -2980,7 +2981,8 @@ impl Default for &str {
}

#[stable(feature = "default_mut_str", since = "1.28.0")]
impl Default for &mut str {
#[rustc_const_unstable(feature = "const_default", issue = "none")]
impl const Default for &mut str {
/// Creates an empty mutable str
#[inline]
fn default() -> Self {
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/tests/ui/or_fun_call.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ fn fn_call_in_nested_expr() {
let opt_foo = Some(Foo {
val: String::from("123"),
});
//~v ERROR: function call inside of `unwrap_or`
let _ = opt_foo.unwrap_or_else(|| Foo { val: String::default() });
// ok, `String::default()` is now `const`
let _ = opt_foo.unwrap_or(Foo { val: String::default() });
}

fn main() {}
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/or_fun_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ fn fn_call_in_nested_expr() {
let opt_foo = Some(Foo {
val: String::from("123"),
});
//~v ERROR: function call inside of `unwrap_or`
// ok, `String::default()` is now `const`
let _ = opt_foo.unwrap_or(Foo { val: String::default() });
}

Expand Down
8 changes: 1 addition & 7 deletions src/tools/clippy/tests/ui/or_fun_call.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,5 @@ error: use of `unwrap_or` to construct default value
LL | let _ = opt.unwrap_or({ i32::default() });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`

error: function call inside of `unwrap_or`
--> tests/ui/or_fun_call.rs:365:21
|
LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })`

error: aborting due to 38 previous errors
error: aborting due to 37 previous errors

6 changes: 3 additions & 3 deletions tests/ui/consts/rustc-impl-const-stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub struct Data {

#[stable(feature = "potato", since = "1.27.0")]
#[rustc_const_unstable(feature = "data_foo", issue = "none")]
impl const Default for Data {
fn default() -> Data {
Data { _data: 42 }
impl const std::fmt::Debug for Data {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
panic!()
}
}
6 changes: 3 additions & 3 deletions tests/ui/consts/rustc-impl-const-stability.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: const `impl` for trait `Default` which is not marked with `#[const_trait]`
error: const `impl` for trait `Debug` which is not marked with `#[const_trait]`
--> $DIR/rustc-impl-const-stability.rs:15:12
|
LL | impl const Default for Data {
| ^^^^^^^ this trait is not `const`
LL | impl const std::fmt::Debug for Data {
| ^^^^^^^^^^^^^^^ this trait is not `const`
|
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
= note: adding a non-const method body in the future would be a breaking change
Expand Down
8 changes: 5 additions & 3 deletions tests/ui/specialization/const_trait_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#![feature(const_trait_impl, min_specialization, rustc_attrs)]

use std::fmt::Debug;

#[rustc_specialization_trait]
#[const_trait]
pub unsafe trait Sup {
Expand Down Expand Up @@ -31,19 +33,19 @@ pub trait A {
fn a() -> u32;
}

impl<T: ~const Default> const A for T {
impl<T: ~const Debug> const A for T {
default fn a() -> u32 {
2
}
}

impl<T: ~const Default + ~const Sup> const A for T {
impl<T: ~const Debug + ~const Sup> const A for T {
default fn a() -> u32 {
3
}
}

impl<T: ~const Default + ~const Sub> const A for T {
impl<T: ~const Debug + ~const Sub> const A for T {
fn a() -> u32 {
T::foo()
}
Expand Down
60 changes: 30 additions & 30 deletions tests/ui/specialization/const_trait_impl.stderr
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const_trait_impl.rs:34:9
--> $DIR/const_trait_impl.rs:36:9
|
LL | impl<T: ~const Default> const A for T {
| ^^^^^^ can't be applied to `Default`
LL | impl<T: ~const Debug> const A for T {
| ^^^^^^ can't be applied to `Debug`
|
note: `Default` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/default.rs:LL:COL
note: `Debug` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL

error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const_trait_impl.rs:40:9
--> $DIR/const_trait_impl.rs:42:9
|
LL | impl<T: ~const Default + ~const Sup> const A for T {
| ^^^^^^ can't be applied to `Default`
LL | impl<T: ~const Debug + ~const Sup> const A for T {
| ^^^^^^ can't be applied to `Debug`
|
note: `Default` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/default.rs:LL:COL
note: `Debug` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL

error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const_trait_impl.rs:46:9
--> $DIR/const_trait_impl.rs:48:9
|
LL | impl<T: ~const Default + ~const Sub> const A for T {
| ^^^^^^ can't be applied to `Default`
LL | impl<T: ~const Debug + ~const Sub> const A for T {
| ^^^^^^ can't be applied to `Debug`
|
note: `Default` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/default.rs:LL:COL
note: `Debug` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL

error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const_trait_impl.rs:40:9
--> $DIR/const_trait_impl.rs:42:9
|
LL | impl<T: ~const Default + ~const Sup> const A for T {
| ^^^^^^ can't be applied to `Default`
LL | impl<T: ~const Debug + ~const Sup> const A for T {
| ^^^^^^ can't be applied to `Debug`
|
note: `Default` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/default.rs:LL:COL
note: `Debug` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const_trait_impl.rs:34:9
--> $DIR/const_trait_impl.rs:36:9
|
LL | impl<T: ~const Default> const A for T {
| ^^^^^^ can't be applied to `Default`
LL | impl<T: ~const Debug> const A for T {
| ^^^^^^ can't be applied to `Debug`
|
note: `Default` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/default.rs:LL:COL
note: `Debug` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/const_trait_impl.rs:46:9
--> $DIR/const_trait_impl.rs:48:9
|
LL | impl<T: ~const Default + ~const Sub> const A for T {
| ^^^^^^ can't be applied to `Default`
LL | impl<T: ~const Debug + ~const Sub> const A for T {
| ^^^^^^ can't be applied to `Debug`
|
note: `Default` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/default.rs:LL:COL
note: `Debug` can't be used with `~const` because it isn't annotated with `#[const_trait]`
--> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: aborting due to 6 previous errors
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/traits/const-traits/const-traits-alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@ run-pass
#![feature(const_trait_impl, const_default)]
#![allow(dead_code)]
// alloc::string
const STRING: String = Default::default();
// alloc::vec
const VEC: Vec<()> = Default::default();

fn main() {}
Loading
Loading