Skip to content
Merged
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
12 changes: 6 additions & 6 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2211,7 +2211,7 @@ pub const unsafe fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
#[rustc_intrinsic_const_stable_indirect]
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_allow_const_fn_unstable(const_trait_impl, funnel_shifts)]
#[rustc_allow_const_fn_unstable(const_trait_impl)]
#[miri::intrinsic_fallback_is_spec]
pub const fn rotate_left<T: [const] fallback::FunnelShift>(x: T, shift: u32) -> T {
// Make sure to call the intrinsic for `funnel_shl`, not the fallback impl.
Expand All @@ -2233,7 +2233,7 @@ pub const fn rotate_left<T: [const] fallback::FunnelShift>(x: T, shift: u32) ->
#[rustc_intrinsic_const_stable_indirect]
#[rustc_nounwind]
#[rustc_intrinsic]
#[rustc_allow_const_fn_unstable(const_trait_impl, funnel_shifts)]
#[rustc_allow_const_fn_unstable(const_trait_impl)]
#[miri::intrinsic_fallback_is_spec]
pub const fn rotate_right<T: [const] fallback::FunnelShift>(x: T, shift: u32) -> T {
// Make sure to call the intrinsic for `funnel_shr`, not the fallback impl.
Expand Down Expand Up @@ -2329,11 +2329,11 @@ pub const fn saturating_sub<T: Copy>(a: T, b: T) -> T;
///
/// Safe versions of this intrinsic are available on the integer primitives
/// via the `funnel_shl` method. For example, [`u32::funnel_shl`].
#[rustc_intrinsic_const_stable_indirect]
#[rustc_intrinsic]
#[rustc_nounwind]
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
#[unstable(feature = "funnel_shifts", issue = "145686")]
#[track_caller]
#[rustc_allow_const_fn_unstable(const_trait_impl, core_intrinsics_fallbacks)]

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.

I just realized that we should not have landed this. This allows core_intrinsics_fallbacks to use arbitrary unstable const things that will then be exposed on stable.

rustc_allow_const_fn_unstable should only be used for lang features, never for library features.

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.

There's still plenty of time to change/revert before it lands on stable on December 24.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What's supposed to happen with core_intrinsics_fallbacks? It looks like this is the first case to use one of those traits.

@RalfJung RalfJung Oct 27, 2026 •

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.

For non-trait fallbacks, what's supposed to happen is that all functions that can be called from stable are tagged #[rustc_const_stable_indirect]. That way we enforce recursive const stability through them.

#[rustc_const_stable_indirect] does not yet support traits. That will have to be fixed. It's not trivial because with traits we cannot in general know which function actually gets called. So we'll have to tag the trait method itself and then have to ensure that all impls are recursively const-checked.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Were things working correctly before? Rotate has been const stable and it was using #[rustc_allow_const_fn_unstable(const_trait_impl, funnel_shifts)] prior to this PR. Maybe we could get away with something similar by moving the traits to core_intrinsics_funnel_shift_fallback to at least limit potential issues.

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.

(Note: the branch would be 12 November.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If anything we could revert the const stabilization. But I don't think this PR caused the issue, so reverting it wouldn't fix it anyway—we still need rustc_allow_const_fn_unstable(some_library_feature) to support the long-existing const stability of rotate_*, unless we effectively revert bc809be and reimplement in the compiler again.

But I don't think that's worth it if there's a reasonable policy to be reached here.

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.

Yeah I don't think we need to revert the stabilization, worst-case we add a native implementation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

#165114 resolves this concern.

#[miri::intrinsic_fallback_is_spec]
pub const unsafe fn unchecked_funnel_shl<T: [const] fallback::FunnelShift>(
Comment on lines +2332 to 2338

@tgross35 tgross35 Aug 13, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Note that const_trait_impl is only needed for the fallback. We could implement a version without it if needed.

The fallback traits are gated behind core_intrinsics_fallbacks, I'm not sure whether there's a cleaner way to do this.

View changes since the review

a: T,
Expand All @@ -2357,11 +2357,11 @@ pub const unsafe fn unchecked_funnel_shl<T: [const] fallback::FunnelShift>(
///
/// Safer versions of this intrinsic are available on the integer primitives
/// via the `funnel_shr` method. For example, [`u32::funnel_shr`]
#[rustc_intrinsic_const_stable_indirect]
#[rustc_intrinsic]
#[rustc_nounwind]
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
#[unstable(feature = "funnel_shifts", issue = "145686")]
#[track_caller]
#[rustc_allow_const_fn_unstable(const_trait_impl, core_intrinsics_fallbacks)]
#[miri::intrinsic_fallback_is_spec]
pub const unsafe fn unchecked_funnel_shr<T: [const] fallback::FunnelShift>(
a: T,
Expand Down
1 change: 0 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@
#![feature(final_associated_functions)]
#![feature(freeze_impls)]
#![feature(fundamental)]
#![feature(funnel_shifts)]
#![feature(impl_restriction)]
#![feature(intra_doc_pointers)]
#![feature(intrinsics)]
Expand Down
26 changes: 10 additions & 16 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,6 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```
/// #![feature(funnel_shifts)]
///
#[doc = concat!("let a = ", $rot_op, "_", stringify!($SelfT), ";")]
#[doc = concat!("let b = ", $fsh_op, "_", stringify!($SelfT), ";")]
///
Expand All @@ -547,10 +545,8 @@ macro_rules! uint_impl {
/// rotating by an unbounded amount like [`rotate_left`](Self::rotate_left) does:
///
/// ```should_panic
/// #![feature(funnel_shifts)]
/// # #![feature(cfg_overflow_checks)]
/// # #[cfg(overflow_checks)] {
///
#[doc = concat!("let a = ", stringify!($SelfT), "::MAX;")]
/// // Okay
#[doc = concat!("let _ = a.rotate_left(", stringify!($SelfT), "::BITS);")]
Expand All @@ -559,8 +555,8 @@ macro_rules! uint_impl {
/// # }
/// # #[cfg(not(overflow_checks))] panic!("fulfill should_panic");
/// ```
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
#[unstable(feature = "funnel_shifts", issue = "145686")]
#[rustc_const_stable(feature = "funnel_shifts", since = "CURRENT_RUSTC_VERSION")]
#[stable(feature = "funnel_shifts", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[inline(always)]
#[rustc_inherit_overflow_checks]
Expand Down Expand Up @@ -597,8 +593,6 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```
/// #![feature(funnel_shifts)]
///
#[doc = concat!("let a = ", $rot_op, "_", stringify!($SelfT), ";")]
#[doc = concat!("let b = ", $fsh_op, "_", stringify!($SelfT), ";")]
///
Expand All @@ -618,10 +612,8 @@ macro_rules! uint_impl {
/// rotating by an unbounded amount like [`rotate_right`](Self::rotate_right) does:
///
/// ```should_panic
/// #![feature(funnel_shifts)]
/// # #![feature(cfg_overflow_checks)]
/// # #[cfg(overflow_checks)] {
///
#[doc = concat!("let a = ", stringify!($SelfT), "::MAX;")]
/// // Okay
#[doc = concat!("let _ = a.rotate_right(", stringify!($SelfT), "::BITS);")]
Expand All @@ -630,8 +622,8 @@ macro_rules! uint_impl {
/// # }
/// # #[cfg(not(overflow_checks))] panic!("fulfill should_panic");
/// ```
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
#[unstable(feature = "funnel_shifts", issue = "145686")]
#[rustc_const_stable(feature = "funnel_shifts", since = "CURRENT_RUSTC_VERSION")]
#[stable(feature = "funnel_shifts", since = "CURRENT_RUSTC_VERSION")]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[inline(always)]
#[rustc_inherit_overflow_checks]
Expand All @@ -654,8 +646,9 @@ macro_rules! uint_impl {
#[doc = concat!("`", stringify!($SelfT) , "::BITS`,")]
/// i.e. when [`funnel_shl`](Self::funnel_shl) would panic.
///
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
#[unstable(feature = "funnel_shifts", issue = "145686")]
#[rustc_const_stable(feature = "funnel_shifts", since = "CURRENT_RUSTC_VERSION")]
#[stable(feature = "funnel_shifts", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_const_fn_unstable(const_trait_impl)]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[inline(always)]
#[track_caller]
Expand All @@ -680,8 +673,9 @@ macro_rules! uint_impl {
#[doc = concat!("`", stringify!($SelfT) , "::BITS`,")]
/// i.e. when [`funnel_shr`](Self::funnel_shr) would panic.
///
#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
#[unstable(feature = "funnel_shifts", issue = "145686")]
#[rustc_const_stable(feature = "funnel_shifts", since = "CURRENT_RUSTC_VERSION")]
#[stable(feature = "funnel_shifts", since = "CURRENT_RUSTC_VERSION")]
#[rustc_allow_const_fn_unstable(const_trait_impl)]
#[must_use = "this returns the result of the operation, without modifying the original"]
#[inline(always)]
#[track_caller]
Expand Down
1 change: 0 additions & 1 deletion library/coretests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
#![feature(fmt_internals)]
#![feature(formatting_options)]
#![feature(freeze)]
#![feature(funnel_shifts)]
#![feature(future_join)]
#![feature(generic_assert_internals)]
#![feature(hasher_prefixfree_extras)]
Expand Down
1 change: 0 additions & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@
#![feature(fmt_internals)]
#![feature(fn_static)]
#![feature(formatting_options)]
#![feature(funnel_shifts)]
#![feature(generic_atomic)]
#![feature(hash_map_internals)]
#![feature(hash_map_macro)]
Expand Down
1 change: 0 additions & 1 deletion library/stdarch/crates/core_arch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
x86_amx_intrinsics,
f16,
aarch64_unstable_target_feature,
funnel_shifts,
avx10_target_feature,
const_trait_impl,
const_cmp,
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/intrinsics/funnel_shl.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(core_intrinsics, funnel_shifts)]
#![feature(core_intrinsics)]

fn main() {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/intrinsics/funnel_shr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(core_intrinsics, funnel_shifts)]
#![feature(core_intrinsics)]

fn main() {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/pass/intrinsics/integer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@run-native
#![feature(core_intrinsics, funnel_shifts)]
#![feature(core_intrinsics)]
use std::intrinsics::*;

fn main() {
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen-llvm/force-intrinsic-fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
//@ revisions: NORMAL FALLBACK
//@ [FALLBACK] compile-flags: -Zforce-intrinsic-fallback
#![feature(core_intrinsics, funnel_shifts)]
#![feature(core_intrinsics)]

// Check the effect of `-Zforce-intrinsic-fallback`.
//
Expand Down
1 change: 0 additions & 1 deletion tests/ui/std/overflow-check-ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//@[WRAP] compile-flags: -C overflow-checks=false

#![feature(cfg_overflow_checks)]
#![feature(funnel_shifts)]

use std::hint::black_box as bb;
use std::{assert_matches, fmt, panic};
Expand Down
Loading