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 10 commits into
base: master
Choose a base branch
from
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(char_max_len)]
#![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 @@ -2611,7 +2611,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 = "67792")]
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 @@ -3895,7 +3895,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 = "67792")]
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 @@ -333,7 +333,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 = "67792")]
impl<T: ~const Default> const Default for Cell<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
impl<T: ~const Default> const Default for Cell<T> {
impl<T: [const] Default> const Default for Cell<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not possible until the bootstrap bump because we use stage 0 rustfmt

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not parsed against the master branch I rebased on top of? Has the parser change already landed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parser changes landed. But rustfmt is bumped when the bootstrap compiler is bumped. At that time everything will automatically be formatted from ~const to [const]

/// Creates a `Cell<T>`, with the `Default` value for T.
#[inline]
fn default() -> Cell<T> {
Expand Down Expand Up @@ -1326,7 +1327,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 = "67792")]
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 @@ -2333,7 +2335,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 = "67792")]
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 @@ -2440,7 +2443,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 = "67792")]
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;
/// ```
#[rustc_diagnostic_item = "Default"]
#[stable(feature = "rust1", since = "1.0.0")]
#[const_trait]
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
pub trait Default: Sized {
/// Returns the "default value" for a type.
///
Expand Down Expand Up @@ -149,7 +151,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 = "67792")]
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 = "67792")]
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 @@ -858,7 +858,8 @@ impl<T: PointeeSized> Clone for PhantomData<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PointeeSized> Default for PhantomData<T> {
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
impl<T: PointeeSized> 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 @@ -2111,7 +2111,8 @@ where
impl<T> crate::clone::UseCloned for Option<T> where T: crate::clone::UseCloned {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Option<T> {
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
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 @@ -230,7 +230,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 = "67792")]
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 @@ -5158,15 +5158,17 @@ where
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for &[T] {
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
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 = "67792")]
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 @@ -3072,7 +3072,8 @@ impl AsRef<[u8]> for str {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Default for &str {
#[rustc_const_unstable(feature = "const_default", issue = "67792")]
impl const Default for &str {
/// Creates an empty str
#[inline]
fn default() -> Self {
Expand All @@ -3081,7 +3082,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 = "67792")]
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 @@ -406,8 +406,8 @@ fn fn_call_in_nested_expr() {
val: String::from("123"),
});

let _ = opt_foo.unwrap_or_else(|| Foo { val: String::default() });
//~^ or_fun_call
// ok, `String::default()` is now `const`
let _ = opt_foo.unwrap_or(Foo { val: String::default() });
}

mod result_map_or {
Expand Down
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 @@ -406,8 +406,8 @@ fn fn_call_in_nested_expr() {
val: String::from("123"),
});

// ok, `String::default()` is now `const`
let _ = opt_foo.unwrap_or(Foo { val: String::default() });
//~^ or_fun_call
}

mod result_map_or {
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 @@ -240,12 +240,6 @@ 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:409:21
|
LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })`
Comment on lines -243 to -247
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this clippy lint have a check that the value is const constructable in a stable way (which would revert this output change)?


error: function call inside of `map_or`
--> tests/ui/or_fun_call.rs:424:19
|
Expand All @@ -264,5 +258,5 @@ error: function call inside of `get_or_insert`
LL | let _ = x.get_or_insert(g());
| ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)`

error: aborting due to 41 previous errors
error: aborting due to 40 previous errors

8 changes: 4 additions & 4 deletions tests/ui/consts/rustc-impl-const-stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//@ known-bug: #110395

#![crate_type = "lib"]
#![feature(staged_api, const_trait_impl)]
#![feature(staged_api, const_trait_impl, const_default)]
#![stable(feature = "foo", since = "1.0.0")]

#[stable(feature = "potato", since = "1.27.0")]
Expand All @@ -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, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
Ok(())
}
}
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
4 changes: 2 additions & 2 deletions tests/ui/lint/dead-code/unused-struct-derive-default.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![deny(dead_code)]
#![deny(dead_code)] //~ NOTE the lint level is defined here

#[derive(Default)]
struct T; //~ ERROR struct `T` is never constructed
Expand All @@ -7,7 +7,7 @@ struct T; //~ ERROR struct `T` is never constructed
struct Used;

#[derive(Default)]
enum E {
enum E { //~ NOTE variant in this enum
#[default]
A,
B, //~ ERROR variant `B` is never constructed
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