diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 538bfc2129017..a7c23dbb79ca5 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -9,6 +9,8 @@ test(attr(deny(warnings))) )] #![feature(box_patterns)] +#![feature(const_default_impls)] +#![feature(const_trait_impl)] #![feature(crate_visibility_modifier)] #![feature(if_let_guard)] #![feature(label_break_value)] diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 70dbda8222445..89a0857992e49 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -128,14 +128,7 @@ impl> Encodable for P { impl P<[T]> { pub const fn new() -> P<[T]> { - // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>` - // (as trait methods, `default` in this case, can't be `const fn` yet). - P { - ptr: unsafe { - use std::ptr::NonNull; - std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>) - }, - } + P { ptr: Box::default() } } #[inline(never)] diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e6faf1df3a810..639e7f213eaae 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1192,17 +1192,25 @@ impl Default for Box { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Box<[T]> { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Box<[T]> { fn default() -> Self { - Box::<[T; 0]>::new([]) + let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling(); + Box(ptr, Global) } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "default_box_extra", since = "1.17.0")] -impl Default for Box { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Box { fn default() -> Self { - unsafe { from_boxed_utf8_unchecked(Default::default()) } + // SAFETY: This is the same as `Unique::cast` but with an unsized `U = str`. + let ptr: Unique = unsafe { + let bytes: Unique<[u8]> = Unique::<[u8; 0]>::dangling(); + Unique::new_unchecked(bytes.as_ptr() as *mut str) + }; + Box(ptr, Global) } } diff --git a/library/alloc/tests/const_fns.rs b/library/alloc/tests/const_fns.rs index f448b3eb7c300..49b837becbcd8 100644 --- a/library/alloc/tests/const_fns.rs +++ b/library/alloc/tests/const_fns.rs @@ -6,6 +6,9 @@ pub const MY_VEC2: Vec = Default::default(); pub const MY_STRING: String = String::new(); pub const MY_STRING2: String = Default::default(); +pub const MY_BOXED_SLICE: Box<[usize]> = Default::default(); +pub const MY_BOXED_STR: Box = Default::default(); + use std::collections::{BTreeMap, BTreeSet}; pub const MY_BTREEMAP: BTreeMap = BTreeMap::new(); @@ -23,6 +26,9 @@ fn test_const() { assert_eq!(MY_VEC, MY_VEC2); assert_eq!(MY_STRING, MY_STRING2); + assert_eq!(MY_VEC, *MY_BOXED_SLICE); + assert_eq!(MY_STRING, *MY_BOXED_STR); + assert_eq!(MAP_LEN, 0); assert_eq!(SET_LEN, 0); assert!(MAP_IS_EMPTY && SET_IS_EMPTY);