diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index e41df43e34bd3..420e74b130598 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -54,10 +54,11 @@ fn inherit_const_stability(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { match def_kind { DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst { .. } => { match tcx.def_kind(tcx.local_parent(def_id)) { - DefKind::Impl { .. } => true, + DefKind::Trait | DefKind::Impl { .. } => true, _ => false, } } + DefKind::Closure => true, _ => false, } } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index d85a63999fe03..7b41023ff31bf 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -108,6 +108,7 @@ #![feature(const_heap)] #![feature(const_index)] #![feature(const_option_ops)] +#![feature(const_result_trait_fn)] #![feature(const_try)] #![feature(copied_into_inner)] #![feature(core_intrinsics)] @@ -173,6 +174,7 @@ #![feature(allocator_internals)] #![feature(allow_internal_unstable)] #![feature(cfg_sanitize)] +#![feature(const_closures)] #![feature(const_precise_live_drops)] #![feature(const_trait_impl)] #![feature(coroutine_trait)] diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index cabf6accf3b53..0309d63cce06d 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -898,9 +898,5 @@ const fn layout_array(cap: usize, elem_layout: Layout) -> Result Ok(layout), - Err(_) => Err(CapacityOverflow.into()), - } + elem_layout.repeat_packed(cap).map_err(const |_| CapacityOverflow.into()) } diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index e09d8495fdeac..936d60fdad73b 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -23,6 +23,7 @@ #![feature(const_destruct)] #![feature(const_heap)] #![feature(const_option_ops)] +#![feature(const_result_trait_fn)] #![feature(const_try)] #![feature(copied_into_inner)] #![feature(core_intrinsics)] @@ -54,6 +55,7 @@ // // Language features: // tidy-alphabetical-start +#![feature(const_closures)] #![feature(const_trait_impl)] #![feature(dropck_eyepatch)] #![feature(min_specialization)] diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index c6a06c133a156..6dc748c568fcd 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -226,13 +226,11 @@ pub const trait Iterator { Self: Sized + [const] Destruct, Self::Item: [const] Destruct, { - // FIXME(const-hack): revert this to a const closure - #[rustc_const_unstable(feature = "const_iter", issue = "92476")] - #[rustc_inherit_overflow_checks] - const fn plus_one(accum: usize, _elem: T) -> usize { - accum + 1 - } - self.fold(0, plus_one) + self.fold( + 0, + #[rustc_inherit_overflow_checks] + const |accum, _elem| accum + 1, + ) } /// Consumes the iterator, returning the last element. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 3451b2976bb73..57ce51bb8c0ed 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -125,6 +125,7 @@ #![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic_equal_alignment)] #![feature(cfg_ub_checks)] +#![feature(const_closures)] #![feature(const_precise_live_drops)] #![feature(const_trait_impl)] #![feature(decl_macro)] diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index 9521213e1bc7e..aaa71786854da 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -1,4 +1,4 @@ -use crate::marker::{Destruct, PhantomData}; +use crate::marker::Destruct; use crate::ops::ControlFlow; /// The `?` operator and `try {}` blocks. @@ -398,25 +398,6 @@ pub(crate) type ChangeOutputType>, V> = /// Not currently planned to be exposed publicly, so just `pub(crate)`. #[repr(transparent)] pub(crate) struct NeverShortCircuit(pub T); -// FIXME(const-hack): replace with `|a| NeverShortCircuit(f(a))` when const closures added. -pub(crate) struct Wrapped T> { - f: F, - p: PhantomData<(T, A)>, -} -#[rustc_const_unstable(feature = "const_never_short_circuit", issue = "none")] -impl T + [const] Destruct> const FnOnce<(A,)> for Wrapped { - type Output = NeverShortCircuit; - - extern "rust-call" fn call_once(mut self, args: (A,)) -> Self::Output { - self.call_mut(args) - } -} -#[rustc_const_unstable(feature = "const_never_short_circuit", issue = "none")] -impl T> const FnMut<(A,)> for Wrapped { - extern "rust-call" fn call_mut(&mut self, (args,): (A,)) -> Self::Output { - NeverShortCircuit((self.f)(args)) - } -} impl NeverShortCircuit { /// Wraps a unary function to produce one that wraps the output into a `NeverShortCircuit`. @@ -424,11 +405,14 @@ impl NeverShortCircuit { /// This is useful for implementing infallible functions in terms of the `try_` ones, /// without accidentally capturing extra generic parameters in a closure. #[inline] - pub(crate) const fn wrap_mut_1(f: F) -> Wrapped + #[rustc_const_unstable(feature = "const_array", issue = "147606")] + pub(crate) const fn wrap_mut_1( + mut f: F, + ) -> impl [const] FnMut(A) -> Self + [const] Destruct where - F: [const] FnMut(A) -> T, + F: [const] FnMut(A) -> T + [const] Destruct, { - Wrapped { f, p: PhantomData } + const move |a| NeverShortCircuit(f(a)) } #[inline] diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 69a01eef88f97..6a10fc22c2e2c 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -3,7 +3,6 @@ use super::{from_raw_parts, memchr}; use crate::ascii; use crate::cmp::{self, BytewiseEq, Ordering}; -use crate::convert::Infallible; use crate::intrinsics::compare_bytes; use crate::marker::Destruct; use crate::mem::SizedTypeProperties; @@ -182,20 +181,12 @@ type AlwaysBreak = ControlFlow; #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const SlicePartialOrd for A { default fn partial_compare(left: &[A], right: &[A]) -> Option { - // FIXME(const-hack): revert this to a const closure once possible - #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] - const fn elem_chain(a: &A, b: &A) -> ControlFlow> { - match PartialOrd::partial_cmp(a, b) { - Some(Ordering::Equal) => ControlFlow::Continue(()), - non_eq => ControlFlow::Break(non_eq), - } - } + let elem_chain = const |a, b| match PartialOrd::partial_cmp(a, b) { + Some(Ordering::Equal) => ControlFlow::Continue(()), + non_eq => ControlFlow::Break(non_eq), + }; - // FIXME(const-hack): revert this to a const closure once possible - #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] - const fn len_chain(a: &usize, b: &usize) -> ControlFlow, Infallible> { - ControlFlow::Break(usize::partial_cmp(a, b)) - } + let len_chain = const |a: &_, b: &_| ControlFlow::Break(usize::partial_cmp(a, b)); let AlwaysBreak::Break(b) = chaining_impl(left, right, elem_chain, len_chain); b @@ -293,20 +284,12 @@ const trait SliceOrd: Sized { #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] impl const SliceOrd for A { default fn compare(left: &[Self], right: &[Self]) -> Ordering { - // FIXME(const-hack): revert this to a const closure once possible - #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] - const fn elem_chain(a: &A, b: &A) -> ControlFlow { - match Ord::cmp(a, b) { - Ordering::Equal => ControlFlow::Continue(()), - non_eq => ControlFlow::Break(non_eq), - } - } + let elem_chain = const |a, b| match Ord::cmp(a, b) { + Ordering::Equal => ControlFlow::Continue(()), + non_eq => ControlFlow::Break(non_eq), + }; - // FIXME(const-hack): revert this to a const closure once possible - #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] - const fn len_chain(a: &usize, b: &usize) -> ControlFlow { - ControlFlow::Break(usize::cmp(a, b)) - } + let len_chain = const |a: &_, b: &_| ControlFlow::Break(usize::cmp(a, b)); let AlwaysBreak::Break(b) = chaining_impl(left, right, elem_chain, len_chain); b