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/array/mod.rs b/library/core/src/array/mod.rs index 12883e252ca86..dc4a2e4fe0003 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -106,11 +106,11 @@ pub fn repeat(val: T) -> [T; N] { #[inline] #[stable(feature = "array_from_fn", since = "1.63.0")] #[rustc_const_unstable(feature = "const_array", issue = "147606")] -pub const fn from_fn(f: F) -> [T; N] +pub const fn from_fn(mut f: F) -> [T; N] where F: [const] FnMut(usize) -> T + [const] Destruct, { - try_from_fn(NeverShortCircuit::wrap_mut_1(f)).0 + try_from_fn(const move |a| NeverShortCircuit(f(a))).0 } /// Creates an array `[T; N]` where each fallible array element `T` is returned by the `cb` call. @@ -580,13 +580,13 @@ impl [T; N] { #[must_use] #[stable(feature = "array_map", since = "1.55.0")] #[rustc_const_unstable(feature = "const_array", issue = "147606")] - pub const fn map(self, f: F) -> [U; N] + pub const fn map(self, mut f: F) -> [U; N] where F: [const] FnMut(T) -> U + [const] Destruct, U: [const] Destruct, T: [const] Destruct, { - self.try_map(NeverShortCircuit::wrap_mut_1(f)).0 + self.try_map(const |a| NeverShortCircuit(f(a))).0 } /// A fallible function `f` applied to each element on array `self` in order to diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index c6a06c133a156..bd342b2a1e12a 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -226,13 +226,7 @@ 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, 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 79694c46f2dcc..c1c979d12207a 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..9be7505555db5 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,39 +398,8 @@ 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`. - /// - /// 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 - where - F: [const] FnMut(A) -> T, - { - Wrapped { f, p: PhantomData } - } - #[inline] pub(crate) fn wrap_mut_2(mut f: impl FnMut(A, B) -> T) -> impl FnMut(A, B) -> Self { move |a, b| NeverShortCircuit(f(a, b)) 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