From 28819e0f4b860f62d2e1748fdc19a1628cc5933c Mon Sep 17 00:00:00 2001 From: "Tim (Theemathas) Chirananthavat" Date: Tue, 21 Oct 2025 14:11:33 +0700 Subject: [PATCH] Make `const Fn` require `const FnMut` --- library/core/src/ops/function.rs | 2 +- tests/ui/traits/const-traits/call.rs | 1 + tests/ui/traits/const-traits/call.stderr | 11 ++++++++++- .../const_closure-const_trait_impl-ice-113381.stderr | 11 ++++++++++- .../non-const-op-const-closure-non-const-outer.rs | 1 + .../non-const-op-const-closure-non-const-outer.stderr | 11 ++++++++++- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index 479368ba8f80..efe5c0871fb8 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -73,7 +73,7 @@ use crate::marker::Tuple; #[fundamental] // so that regex can rely that `&str: !FnMut` #[must_use = "closures are lazy and do nothing unless called"] #[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")] -pub const trait Fn: FnMut { +pub const trait Fn: [const] FnMut { /// Performs the call operation. #[unstable(feature = "fn_traits", issue = "29625")] extern "rust-call" fn call(&self, args: Args) -> Self::Output; diff --git a/tests/ui/traits/const-traits/call.rs b/tests/ui/traits/const-traits/call.rs index b1080fe78bb5..65b75cfe5cb2 100644 --- a/tests/ui/traits/const-traits/call.rs +++ b/tests/ui/traits/const-traits/call.rs @@ -6,6 +6,7 @@ pub const _: () = { assert!((const || true)()); //~^ ERROR }: [const] Fn()` is not satisfied + //~| ERROR }: [const] FnMut()` is not satisfied }; fn main() {} diff --git a/tests/ui/traits/const-traits/call.stderr b/tests/ui/traits/const-traits/call.stderr index 8e32cab6dfcf..b688746e2506 100644 --- a/tests/ui/traits/const-traits/call.stderr +++ b/tests/ui/traits/const-traits/call.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] Fn()` LL | assert!((const || true)()); | ^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/call.rs:7:14: 7:22}: [const] FnMut()` is not satisfied + --> $DIR/call.rs:7:13 + | +LL | assert!((const || true)()); + | ^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr index dab3f14161fa..90e87c724f54 100644 --- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr +++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice- LL | (const || (()).foo())(); | ^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/const_closure-const_trait_impl-ice-113381.rs:15:6: 15:14}: [const] FnMut()` is not satisfied + --> $DIR/const_closure-const_trait_impl-ice-113381.rs:15:5 + | +LL | (const || (()).foo())(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs index d0470fa34584..ee4ff02f4c7c 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs @@ -12,4 +12,5 @@ impl Foo for () { fn main() { (const || { (()).foo() })(); //~^ ERROR: }: [const] Fn()` is not satisfied + //~| ERROR: }: [const] FnMut()` is not satisfied } diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr index dcf65ab69408..69d289537da1 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr @@ -4,6 +4,15 @@ error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-cons LL | (const || { (()).foo() })(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:13:6: 13:14}: [const] FnMut()` is not satisfied + --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5 + | +LL | (const || { (()).foo() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required by a bound in `call` + --> $SRC_DIR/core/src/ops/function.rs:LL:COL + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`.