Skip to content
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
3 changes: 2 additions & 1 deletion compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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)]
Expand Down
6 changes: 1 addition & 5 deletions library/alloc/src/raw_vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,9 +898,5 @@ const fn layout_array(cap: usize, elem_layout: Layout) -> Result<Layout, TryRese
// which lets us use the much-simpler `repeat_packed`.
debug_assert!(elem_layout.size() == elem_layout.pad_to_align().size());

// FIXME(const-hack) return to using `map` and `map_err` once `const_closures` is implemented
match elem_layout.repeat_packed(cap) {
Copy link
Copy Markdown
Contributor

@bend-n bend-n Apr 29, 2026

Choose a reason for hiding this comment

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

why isn't it repeat_packed?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think this was a very recent change and I messed up a rebase over it, fixed

Ok(layout) => Ok(layout),
Err(_) => Err(CapacityOverflow.into()),
}
elem_layout.repeat_packed(cap).map_err(const |_| CapacityOverflow.into())
}
2 changes: 2 additions & 0 deletions library/alloctests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -54,6 +55,7 @@
//
// Language features:
// tidy-alphabetical-start
#![feature(const_closures)]
#![feature(const_trait_impl)]
#![feature(dropck_eyepatch)]
#![feature(min_specialization)]
Expand Down
8 changes: 4 additions & 4 deletions library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ pub fn repeat<T: Clone, const N: usize>(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<T: [const] Destruct, const N: usize, F>(f: F) -> [T; N]
pub const fn from_fn<T: [const] Destruct, const N: usize, F>(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
Copy link
Copy Markdown
Contributor Author

@oli-obk oli-obk Apr 29, 2026

Choose a reason for hiding this comment

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

Yea, the Wrapped type was only used in these two cases

View changes since the review

}

/// Creates an array `[T; N]` where each fallible array element `T` is returned by the `cb` call.
Expand Down Expand Up @@ -580,13 +580,13 @@ impl<T, const N: usize> [T; N] {
#[must_use]
#[stable(feature = "array_map", since = "1.55.0")]
#[rustc_const_unstable(feature = "const_array", issue = "147606")]
pub const fn map<F, U>(self, f: F) -> [U; N]
pub const fn map<F, U>(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
Expand Down
8 changes: 1 addition & 7 deletions library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: [const] Destruct>(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.
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
33 changes: 1 addition & 32 deletions library/core/src/ops/try_trait.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::marker::{Destruct, PhantomData};
use crate::marker::Destruct;
use crate::ops::ControlFlow;

/// The `?` operator and `try {}` blocks.
Expand Down Expand Up @@ -398,39 +398,8 @@ pub(crate) type ChangeOutputType<T: Try<Residual: Residual<V>>, V> =
/// Not currently planned to be exposed publicly, so just `pub(crate)`.
#[repr(transparent)]
pub(crate) struct NeverShortCircuit<T>(pub T);
// FIXME(const-hack): replace with `|a| NeverShortCircuit(f(a))` when const closures added.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are these simply not needed any more?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yeah, they were only for wrap_mut_1. but, i think the wrap_mut_1 function should still exist? it wasnt added as a const hack.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hmm... I guess we could keep it and return a const closure from it, but is it really worth it?

Copy link
Copy Markdown
Contributor

@bend-n bend-n Apr 29, 2026

Choose a reason for hiding this comment

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

i mean i think so.. thats what was done pre const hack at least, and i dont think it was a bad design?
the fixme i wrote on the const-hack was intended to be put in wrap_mut_1

pub(crate) struct Wrapped<T, A, F: FnMut(A) -> T> {
f: F,
p: PhantomData<(T, A)>,
}
#[rustc_const_unstable(feature = "const_never_short_circuit", issue = "none")]
impl<T, A, F: [const] FnMut(A) -> T + [const] Destruct> const FnOnce<(A,)> for Wrapped<T, A, F> {
type Output = NeverShortCircuit<T>;

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, A, F: [const] FnMut(A) -> T> const FnMut<(A,)> for Wrapped<T, A, F> {
extern "rust-call" fn call_mut(&mut self, (args,): (A,)) -> Self::Output {
NeverShortCircuit((self.f)(args))
}
}

impl<T> NeverShortCircuit<T> {
/// 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<A, F>(f: F) -> Wrapped<T, A, F>
where
F: [const] FnMut(A) -> T,
{
Wrapped { f, p: PhantomData }
}

#[inline]
pub(crate) fn wrap_mut_2<A, B>(mut f: impl FnMut(A, B) -> T) -> impl FnMut(A, B) -> Self {
move |a, b| NeverShortCircuit(f(a, b))
Expand Down
37 changes: 10 additions & 27 deletions library/core/src/slice/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -182,20 +181,12 @@ type AlwaysBreak<B> = ControlFlow<B, crate::convert::Infallible>;
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: [const] PartialOrd> const SlicePartialOrd for A {
default fn partial_compare(left: &[A], right: &[A]) -> Option<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: [const] PartialOrd>(a: &A, b: &A) -> ControlFlow<Option<Ordering>> {
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<Option<Ordering>, 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
Expand Down Expand Up @@ -293,20 +284,12 @@ const trait SliceOrd: Sized {
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: [const] Ord> 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: [const] Ord>(a: &A, b: &A) -> ControlFlow<Ordering> {
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<Ordering, Infallible> {
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
Expand Down
Loading